1

使用 Perl find 我无法成功转义搜索字符串中的 DOCTYPE 声明。这是我正在搜索的字符串的示例;

find . -type f|xargs -d "\n" perl -pi -e 's/ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1\.0 Transitional//EN" "http://www\.w3\.org/TR/xhtml1/DTD/xhtml1-transitional\.dtd">//g'  

用任何内容替换 doctype 声明。请如果有人可以正确地转义这个字符串,以便 perl find 可以找到任何字符串,将不胜感激。

4

4 回答 4

4

正如另一个人所建议的那样,'/'您的正则表达式中的各种字符需要用 a 转义,'\'因为 Perl 会将它们读作s///;过早结束,否则会导致一些错误。在处理这些时,您总是必须注意特殊字符,正如我看到您在各个时期所做的那样。

's/ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1\.0 Transitional//EN" "http://www\.w3\.org/TR/xhtml1/DTD/xhtml1-transitional\.dtd">//g' 

您可以将 a 中的分隔符更改s///;为其他内容,例如 s###s{}{}以帮助缓解问题,如果您使用 HTML,我通常建议您这样做。

即便如此,我会说尽量简化正则表达式以适应应用程序。因为像这样的 HTML 使用起来可能很讨厌,所以尝试使用非贪婪匹配任何类型的正则表达式,但使用<and>来捕获特定标签。例如,您可能会使用这样的正则表达式...

s{<!DOCTYPE .*?>}{}s

和一些解释的格式......

s{
    <!DOCTYPE   # opening doctype tag
    \s          # one whitepsace
    .*?         # anything (even newlines because of /s flag) non-greedily
     >          # until the first closing greater than 
}{}xs;          # x is ignore whitespace, s is have '.' match anything (even \n)

此示例使用/x标志将其注释掉并解释所有内容,但如果您在命令行上执行此操作,则没有必要这样做。

我不能谈论你问题的其余部分,因为我对 shell 命令不太熟悉,只对正则表达式部分。

于 2012-11-13T23:15:56.867 回答
2

/除了在 Perl 中,您还可以使用其他分隔符。试试这个:

s{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1\.0 Transitional//EN" "http://www\.w3\.org/TR/xhtml1/DTD/xhtml1-transitional\.dtd">}{}g

由于斜线不再分隔正则表达式,因此可以安全使用。

于 2012-11-13T21:56:14.197 回答
0

如果在DOCTYPE一行,最好这样写:

find . -type f -exec sed -i '/DOCTYPE/d' {} +

或在perl

find . -type f -exec perl -i -ne 'print unless /DOCTYPE/' {} +

以避免保留空白行。

笔记

  • -i开关修改文件。出于测试目的将其删除
于 2012-11-13T22:03:30.280 回答
0

虽然已经涵盖了备用分隔符(例如s###),但我会添加 using\Q\E删除其他转义需求:

s#\Q<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\E##g' 
于 2012-11-14T00:54:56.993 回答