给定someletters_12345_moreleters形式的文件名。ext,我想提取5位数字,并将它们放入一个变量。

为了强调这一点,我有一个x个字符的文件名,然后是一个5位数字序列,两边都有一个下划线,然后是另一组x个字符。我想把这个5位数代入一个变量。

我对实现这一目标的多种不同方式非常感兴趣。


当前回答

基于jor的回答(这对我来说并不适用):

substring=$(expr "$filename" : '.*_\([^_]*\)_.*')

其他回答

您可以使用参数展开来做到这一点。

如果a为常数,则下面的参数展开执行子字符串提取:

b=${a:12:5}

12是偏移量(从零开始),5是长度

如果数字周围的下划线是输入中唯一的下划线,您可以分两步分别去掉前缀和后缀:

tmp=${a#*_}   # remove prefix ending in "_"
b=${tmp%_*}   # remove suffix starting with "_"

如果有其他下划线,那么无论如何都可能是可行的,尽管比较棘手。如果有人知道如何在一个表达式中执行两个展开,我也想知道。

提出的两个解决方案都是纯bash,不涉及进程生成,因此非常快。

没有任何子过程,您可以:

shopt -s extglob
front=${input%%_+([a-zA-Z]).*}
digits=${front##+([a-zA-Z])_}

一个非常小的变体也可以在ksh93中工作。

遵循要求

我有一个文件名,x个字符,然后是5位数字 序列两侧分别用一个下划线包围 x个字符的集合。我想取一个5位数 把它代入一个变量。

我发现了一些可能有用的grep方法:

$ echo "someletters_12345_moreleters.ext" | grep -Eo "[[:digit:]]+" 
12345

或更好的

$ echo "someletters_12345_moreleters.ext" | grep -Eo "[[:digit:]]{5}" 
12345

然后使用-Po语法:

$ echo "someletters_12345_moreleters.ext" | grep -Po '(?<=_)\d+' 
12345

或者如果你想让它正好适合5个字符:

$ echo "someletters_12345_moreleters.ext" | grep -Po '(?<=_)\d{5}' 
12345

最后,要将它存储在一个变量中,只需要使用var=$(命令)语法。

给定test.txt文件包含"ABCDEFGHIJKLMNOPQRSTUVWXYZ"

cut -b19-20 test.txt > test1.txt # This will extract chars 19 & 20 "ST" 
while read -r; do;
> x=$REPLY
> done < test1.txt
echo $x
ST

还有bash内置的'expr'命令:

INPUT="someletters_12345_moreleters.ext"  
SUBSTRING=`expr match "$INPUT" '.*_\([[:digit:]]*\)_.*' `  
echo $SUBSTRING