我需要递归查找并替换.cpp
和.hpp
个文件中的字符串。
查看this question的答案我找到了以下命令:
find /home/www -type f -print0 | xargs -0 sed -i 's/subdomainA.example.com/subdomainB.example.com/g'
将其更改为包含我的文件类型无效 - 未更改任何单个词:
find /myprojects -type f -name *.cpp -print0 | xargs -0 sed -i 's/previousword/newword/g'
帮助表示赞赏。
答案 0 :(得分:3)
不要为xargs
而烦恼;使用-exec
主要版本。 (为了便于阅读,分为两行。)
find /home/www -type f -name '*.cpp' \
-exec sed -i 's/previousword/newword/g' '{}' \;
答案 1 :(得分:2)
chepner's helpful answer建议更简单,更有效地使用find
-exec
行动,而不是管道xargs
。< / p>
除非需要特殊的xargs
功能,否则此更改总是值得的,并映射到xargs
功能,如下所示:
find ... -exec ... {} \;
相当于find ... -print0 | xargs -0 -n 1 ...
find ... -exec ... {} +
相当于find ... -print0 | xargs -0 ...
换句话说:
\;
终止符为每个匹配的文件/文件夹调用一次目标命令。
+
终结符一次性调用目标命令 ,将所有匹配的文件/文件夹路径作为单个参数列表提供。
getconf ARG_MAX
,最大值。命令行长度很大。对OP的命令进行排查:
由于OP的xargs
命令一次性传递所有匹配的文件路径 - 并且每个xargs
默认值 end 在命令行中,生成的命令将实际看起来像这样:
sed -i 's/previousword/newword/g' /myprojects/file1.cpp /myprojects/file2.cpp ...
这可以通过将echo
添加到sed
来轻松验证 - 但是(概念性地)引用需要它的参数(带有例如嵌入空格的路径)将不会显示(注意{{1} }}):
echo
接下来,在运行实际命令后,使用find /myprojects -type f -name '*.cpp' -print0 |
xargs -0 echo sed -i 's/previousword/newword/g'
检查文件的上次修改日期是否已更改:
stat
已处理文件,但sed
函数调用中的正则表达式没有匹配任何东西。 可以想象在将s
(就地编辑)与多个sed版本无法正常工作>文件操作数(虽然我在GNU sed
release notes中找不到任何内容)
要对此进行排除,请为每个文件调用-i
:
如果您仍想使用sed
,请添加xargs
:
-n 1
要使用 find /myprojects -type f -name '*.cpp' -print0 |
xargs -0 -n 1 sed -i 's/previousword/newword/g'
&#39; find
操作,请参阅chepner's answer。
使用GNU -exec
版本支持使用sed
选项更新多个文件 - 至少的情况是这样的 v4.2.2 - 命令的最佳表述是(注意引用-i
参数以防止shell过早扩展,并使用终结符*.cpp
仅调用+
一次):
sed