使用 [ ] 访问大于 9 的数字系列

access series of numbers higher than 9 with [ ]

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

字符 class,如 [0-9][a-f],根据定义仅匹配单个字符。它们本身不匹配 "numbers"——即使给定的数字是数字,它们也仅被视为字符代码点,而不是数字值。 fnmatch() 样式模式(shell 在此使用)与正则表达式中的相同。


如果您想要 0-50,可以通过组合多个字符 classes 来实现通配行为(仅匹配存在的文件),如下所示:

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?因为如果不存在 myfile50,您不希望 myfile5[0] 作为文字文件名传递,否则这是默认行为)。


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])