下面的命令正确地更改了2个文件的内容。
sed -i 's/abc/xyz/g' xaa1 xab1
但是我需要动态更改几个这样的文件,我不知道文件名。我想写一个命令,将读取当前目录下以xa*开头的所有文件,sed应该改变文件内容。
下面的命令正确地更改了2个文件的内容。
sed -i 's/abc/xyz/g' xaa1 xab1
但是我需要动态更改几个这样的文件,我不知道文件名。我想写一个命令,将读取当前目录下以xa*开头的所有文件,sed应该改变文件内容。
当前回答
您可以同时使用grep和sed。这允许您递归地搜索子目录。
Linux: grep -r -l <old> * | xargs sed -i 's/<old>/<new>/g'
OS X: grep -r -l <old> * | xargs sed -i '' 's/<old>/<new>/g'
For grep:
-r recursively searches subdirectories
-l prints file names that contain matches
For sed:
-i extension (Note: An argument needs to be provided on OS X)
其他回答
更好的是:
for i in xa*; do
sed -i 's/asd/dfg/g' $i
done
因为没有人知道有多少文件,而且很容易打破命令行限制。
下面是当文件太多时会发生的情况:
# grep -c aaa *
-bash: /bin/grep: Argument list too long
# for i in *; do grep -c aaa $i; done
0
... (output skipped)
#
您可以同时使用grep和sed。这允许您递归地搜索子目录。
Linux: grep -r -l <old> * | xargs sed -i 's/<old>/<new>/g'
OS X: grep -r -l <old> * | xargs sed -i '' 's/<old>/<new>/g'
For grep:
-r recursively searches subdirectories
-l prints file names that contain matches
For sed:
-i extension (Note: An argument needs to be provided on OS X)
我很惊讶没有人提到-exec参数来查找,这是为这种类型的用例准备的,尽管它将为每个匹配的文件名启动一个进程:
find . -type f -name 'xa*' -exec sed -i 's/asd/dsg/g' {} \;
或者,也可以使用xargs,这样可以调用更少的进程:
find . -type f -name 'xa*' | xargs sed -i 's/asd/dsg/g'
或者更简单地使用+ exec变体而不是;在find中允许find为每个子进程调用提供多个文件:
find . -type f -name 'xa*' -exec sed -i 's/asd/dsg/g' {} +
上面有一些很好的答案。我想我要再加上一个简洁且可并行的方法,使用GNU并行,我通常更喜欢xargs:
parallel sed -i 's/abc/xyz/g' {} ::: xa*
将此选项与-j N选项结合起来,可以并行运行N个作业。
@PaulR将此作为评论发布,但人们应该将其视为一个答案(这个答案最符合我的需求):
sed -i 's/abc/xyz/g' xa*
这将适用于中等数量的文件,可能是几十个,但可能不是几百万个。