find
我正在尝试计算用和替换的字符串的数量sed
。
我首先要说的是:
# find . -name \*.php -exec sed -i -e "s|finddddd|replaceeeee|g" {} \;
这替换了“finddddd”的四个匹配项。运行此命令后,我重置了测试文件,以便该命令再次起作用。
我尝试使用wc -l
,该命令找到并替换了“findddd”的实例,但显示在下面的行中找到了 0 个匹配项。
# find . -name \*.php -exec sed -i -e "s|finddddd|replaceeeee|g" {} \; | wc -l
0
还尝试移动wc -l
命令,但出现错误。
find . -name \*.php -exec sed -i -e "s|finddddd|replaceeeee|g" {}| wc -l;
find: missing argument to `-exec'
0
和
find . -name \*.php -exec sed -i -e "s|finddddd|replaceeeee|g" | wc -l {} \;
wc: {}: No such file or directory
wc: ;: No such file or directory
0 total
find: missing argument to `-exec'
如何让基本命令输出匹配数?
答案1
您使用了错误的工具。wc
将计算输入行数,但由于您使用的是sed -i
,所以没有打印行,所以没有什么可计算wc
的。即使没有它,该sed
命令也会打印文件的所有行,因此它仍然无法正常工作。这是一种不同的方法:
使用 perl 代替
find . -name \*.php \ -exec perl -i -lpe 's|finddddd|replaceeeee|g && print STDERR "."' {} \; \ 2>&1 | wc -l
诀窍是
.
每次替换成功时打印 a ,然后将结果传递给wc
。该-i
标志会就地编辑文件,并导致在每个调用-l
中添加换行符。print
告诉-p
perl 在应用 传递的脚本后打印每个输入行-e
。因为我们正在就地编辑文件,所以我们需要打印到 STDERR 以避免将其.
添加到文件中。然后 STDERR 被重定向到 STDOUT(2>&1
),让我们可以使用wc
.如果需要分别统计同一行的多个替换,请再次使用perl:
find . -name \*.php -exec \ perl -i -lpe '$l++ while s|finddddd|replaceeeee|; END{print STDERR $l}' {} + 2>&1
这里,perl 本身正在进行计数。请注意,我使用了
+
而不是\;
结束-exec
通话。这意味着它将尝试将命令组合成尽可能少的命令。如果您没有太多.php
文件,它们将全部传递到一次perl
运行,并且数量将是正确的。如果你有太多文件,这将会失败,你应该使用这个:find . -name \*.php -exec \ perl -lpe '$l++ while s|finddddd|replaceeeee|; END{print STDERR $l}' {} + 2>&1 >/dev/null | awk '{k+=$1; }END{print k}'