从文件名中选择性地提取数字

时间:2015-04-08 01:40:46

标签: regex bash grep

我有一个文件列表,格式为:AA13_11BBCC290_23DDEE92_34RR。我只需要提取_字符后面的数字,而不是前面的数字。对于这三个文件名,我希望得到11,23,34作为输出,每次提取后,将数字存储到变量中。

我对bash和regex很新。目前,从AA13_11BB,我可以获得13_11:

for imgs in $DIR; do
LEVEL=$(echo $imgs | egrep -o [_0-9]+);
done

或两个单独的数字13和11:

LEVEL=$(echo $imgs | egrep -o [0-9]+) 

我可以请一些建议如何获得我想要的输出?谢谢!

4 个答案:

答案 0 :(得分:2)

egrepsed

一起使用
LEVEL=$(echo $imgs | egrep -o '_[0-9]+' | sed 's/_//' )

答案 1 :(得分:2)

您可以使用正则表达式sed在一个.*_([0-9]+).*内执行此操作(正确转义sed):

sed "s/.*_\([0-9]\+\).*/\1/" <<< "AA13_11BB"

它用第一个captured group()内的子正则表达式)替换该行,输出:

11

在你的剧本中:

LEVEL=$(sed "s/.*_\([0-9]\+\).*/\1/" <<< $imgs) 

更新:按照@mklement0的建议,在 BSD sed GNU sed 中,您可以使用{缩短命令{1}}参数:

-E

答案 2 :(得分:2)

使用hjpotter92's answer的核心

来补充现有的有用答案

以下处理命令中的$DIR 所有文件名将所有提取的令牌读入阵列

IFS=$'\n' read -d '' -ra levels < \
  <(printf '%s\n' "$DIR"/* | egrep -o '_[0-9]+' | sed 's/_//')
  • IFS=$'\n' read -d '' -ra levels将输入拆分为行并将其存储为数组${levels[@]}的元素。
  • <(...)process substitution,它允许命令的输出充当(短暂的)输入文件。
  • printf '%s\n' "$DIR"/*使用路径名扩展来输出各自的文件名。
  • egrep -o '_[0-9]+' | sed 's/_//'hjpotter92's answer中的相同 - 它在多个输入行中的作用相同,就像这里的情况一样。

要稍后处理提取的标记,请使用:

for level in "${levels[@]}"; do
  echo "$level" # work with $level
done

答案 3 :(得分:1)

grep-P标志

一起使用
for imgs in $DIR
do 
    LEVEL=$(echo $imgs |  grep -Po '(?<=_)[0-9]{2}')
    echo $LEVEL
done