Perl 正则表达式在多个文件组中递归替换字符串,如 "*.php" "*.html"

Perl regular expression to replace string recursively in multiple file groups, like "*.php" "*.html"

以下命令不起作用,什么都不做:

sudo find /srv/my/directory -type f -iname '*.htm*' -iname '*.old1' -iname '*.php' | sudo xargs -iX sudo perl -p -i -e 's|\<\?php.*123456.*123456.*\?\>\r?\n\<\?php|<?php|g' 'X'

它不会替换文件中的任何内容。

怎么了?

解决方案:

sudo find /srv/my/directory -type f -iname '*.htm*' -or -iname '*.old1' -or -iname '*.php' | sudo xargs -iX sudo perl -0777 -p -i -e 's|\<\?php.*123456.*123456.*\?\>\r?\n\<\?php|<?php|g' 'X'

解决方案 2(扩展正则表达式中多种情况的能力):

sudo find /srv/my/directory -type f -iname '*.htm*' -or -iname '*.old1' -or -iname '*.php' | sudo xargs -iX sudo perl -0777 -p -i -e 's@\<\?php.*123456.*123456.*\?\>(\r?\n|\#\!.*)\<\?php@<?php@gs' 'X'
  1. 当为 find 指定多个条件时,它们默认通过隐式 -and 连接。没有文件可以匹配 -iname '*.old1' -and -iname '*.php'。您必须明确指定 -or

  2. 除非另有说明,否则 perl -p 会逐行读取文件,因此无法匹配 \n<。使用 -0777 读取整个文件而不是逐行处理它。

sudo find /srv/my/directory -type f \
    -iname '*.htm*' -or -iname '*.old1' -or -iname '*.php' \
    | sudo xargs -iX sudo perl -0777 -p -i \
        -e 's/<\?php.*123456.*123456.*\?>\r?\n<\?php/<?php/g' 'X'

顺便说一句,您不需要在 Perl 正则表达式中使用反斜杠 <>