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