使用 sed 返回查找/替换的匹配项计数

使用 sed 返回查找/替换的匹配项计数

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命令也会打印文件的所有行,因此它仍然无法正常工作。这是一种不同的方法:

  1. 使用 perl 代替

    find . -name \*.php \
      -exec perl -i -lpe 's|finddddd|replaceeeee|g && print STDERR "."' {} \;  \
    2>&1 | wc -l
    

    诀窍是.每次替换成功时打印 a ,然后将结果传递给wc。该-i标志会就地编辑文件,并导致在每个调用-l中添加换行符。print告诉-pperl 在应用 传递的脚本后打印每个输入行-e。因为我们正在就地编辑文件,所以我们需要打印到 STDERR 以避免将其.添加到文件中。然后 STDERR 被重定向到 STDOUT( 2>&1),让我们可以使用wc.

  2. 如果需要分别统计同一行的多个替换,请再次使用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}'
    

相关内容