使用[]访问高于9的数字序列

时间:2016-04-26 00:29:58

标签: bash numbers series

我想用sed更改一系列编号的文件名(超过10个)的文件。 0 - 9我可以使用sed -i 's/old/new/g' myfile[0-9]轻松访问,但这似乎不适用于高于10的数字。我怎么能这样做呢?比如[0-50]

1 个答案:

答案 0 :(得分:6)

根据定义,字符类(如[0-9][a-f])仅匹配单个字符。它们本身与“数字”不匹配 - 即使给出的数字是数字,它们也只被视为字符代码点,而不是数字值。这与fnmatch() - 样式模式(由shell使用)在正则表达式中是一样的。

如果你想要0-50,可以通过组合多个字符类来完成全局行为(仅匹配存在的文件),如下所示:

shopt -s nullglob # if no files match, return empty result
files=( myfile[0-9] myfile[1-4][0-9] myfile5[0] )

# if list of files is nonzero, run sed:
(( ${#files[@]} )) && sed -i -e 's/old/new/g' "${files[@]}"

解释其工作原理:

  • myfile[1-9]匹配1-9(如果存在)
  • myfile[1-4][0-9]匹配10-49(如果存在)
  • myfile5[0]匹配50,当且仅当它存在。

将文件列表放入数组并检查数组的长度,确保在没有列出任何文件名的情况下不运行sed,否则可能会因nullglob而发生这种情况。 (为什么在这里使用nullglob?因为如果不存在myfile5[0],你不希望myfile50作为文字文件名传递,否则这是默认行为。

还有一些POSIX sh标准的附加扩展:

如果您不关心文件是否存在(并且希望将内容放在命令行中,即使它们不存在),您也可以使用大括号扩展:

sed -i -e 's/old/new/g' myfile{0..50}

或者,如果您只关心在文件名末尾匹配一个或多个数字,您可以使用extglobs:

shopt -s extglob
sed -i -e 's/old/new/g' myfile+([0-9])