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

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

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


当前回答

使用sed replace的简单方法:

result=$(echo "someletters_12345_moreleters.ext" | sed 's/.*_\(.*\)_.*/\1/g')
echo $result

其他回答

类似于php中的substr('abcdefg', 2-1, 3):

echo 'abcdefg'|tail -c +2|head -c 3

外壳切割-从字符串中打印特定范围的字符或给定部分

#method1)使用bash

 str=2020-08-08T07:40:00.000Z
 echo ${str:11:8}

#方法2)使用cut

 str=2020-08-08T07:40:00.000Z
 cut -c12-19 <<< $str

#method3)当使用awk时

 str=2020-08-08T07:40:00.000Z
 awk '{time=gensub(/.{11}(.{8}).*/,"\\1","g",$1); print time}' <<< $str

有点晚了,但我刚刚遇到了这个问题,并发现了以下内容:

host:/tmp$ asd=someletters_12345_moreleters.ext 
host:/tmp$ echo `expr $asd : '.*_\(.*\)_'`
12345
host:/tmp$ 

我用它在一个没有%N日期的嵌入式系统上获得毫秒分辨率:

set `grep "now at" /proc/timer_list`
nano=$3
fraction=`expr $nano : '.*\(...\)......'`
$debug nano is $nano, fraction is $fraction

我喜欢sed处理正则表达式组的能力:

> var="someletters_12345_moreletters.ext"
> digits=$( echo "$var" | sed "s/.*_\([0-9]\+\).*/\1/p" -n )
> echo $digits
12345

一个更一般的选择是不要假设你用下划线_标记你的数字序列的开始,因此例如剥离你在你的序列之前得到的所有非数字:s/[^0-9]\+\([0-9]\+\).*/\1/p。


> man sed | grep s/regexp/replacement -A 2
s/regexp/replacement/
    Attempt to match regexp against the pattern space.  If successful, replace that portion matched with replacement.  The replacement may contain the special  character  &  to
    refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.

更多关于这一点,以防你对regexp不太自信:

S代表_s_substitute [0-9]+匹配1+数字 \1链接到正则表达式输出的组n.1(组0是整个匹配,组1是括号内的匹配) P标志为_p_printing

所有转义\都是为了使sed的regexp处理工作。

很多过时的解决方案都需要管道和子外壳。 自bash版本3(2004年发布)以来,它有一个内置的正则表达式比较操作符=~。

input="someletters_12345_moreleters.ext"
# match: underscore followed by 1 or more digits followed by underscore
[[ $input =~ _([0-9]+)_ ]]
echo ${BASH_REMATCH[1]}

输出:

12345

注意,如果您不是很精通编写RegExp,我建议您阅读精通正则表达式。

如果您只是需要弄清楚如何让RegExp工作,并且它不符合您的想法,请尝试RegEx101.com的在线GUI,并将“Flavor”设置为“PCRE”,以便获得bash使用的[[:digit:]]等POSIX风格的字符类。