Linux下如何在多个文件中搜索并替换长段HTML内容?
问题原因分析
- sed 默认按行读取处理文本,默认状态下无法直接匹配跨行的内容,你之前的写法是匹配带换行的多行字符串,sed默认处理不了
- 你写的替换规则里多了一行重复的
<meta name="google" value="notranslate">,会导致替换后出现冗余代码
可用解决方案
这里给两个可直接使用的方案:
方案1:使用GNU sed 多行模式(适配你原来的命令写法)
因为你grep已经加了-z参数输出NUL分隔的文件名,sed也加-z参数整文件读取即可,命令如下:
grep --include="index.html" -PRwzl -e '<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>\n <meta charset="utf-8">\n <meta name="google" value="notranslate">\n' | xargs -0 sed -i -z 's/<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>\n <meta charset="utf-8">\n <meta name="google" value="notranslate">\n/& <meta name="format-detection" content="telephone=no">\n <meta name="format-detection" content="date=no">\n <meta name="format-detection" content="address=no">\n <meta name="format-detection" content="email=no">\n/g'
说明:sed替换语法里的
&代表匹配到的原内容,不用重复手写一遍原字符串,既减少代码量也避免手写出错;同时xargs加了-0参数适配grep输出的NUL分隔的文件名,处理带空格的文件名也不会出错。
方案2:使用perl实现多行替换(兼容性更好,跨平台也能用)
如果你的环境没有GNU sed(比如macOS默认的BSD sed不支持-z参数),可以用perl来实现,命令更稳定:
grep --include="index.html" -PRwzl -e '<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>\n <meta charset="utf-8">\n <meta name="google" value="notranslate">\n' | xargs -0 perl -0777 -i -pe 's/<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>\n <meta charset="utf-8">\n <meta name="google" value="notranslate">\n/$& <meta name="format-detection" content="telephone=no">\n <meta name="format-detection" content="date=no">\n <meta name="format-detection" content="address=no">\n <meta name="format-detection" content="email=no">\n/g'
说明:perl的
-0777参数代表整文件读入处理,-i参数直接修改原文件,$&和sed里的&作用一致,代表匹配到的原内容。
注意事项
操作前建议先备份相关文件,避免误操作导致数据丢失,可以先把sed/perl的-i参数去掉,先输出替换后的内容确认没问题再加上-i执行修改。如果是macOS系统使用BSD sed,-i参数需要加空后缀,比如改成sed -i '' -z ...。
内容的提问来源于stack exchange,提问作者standac
相关产品推荐
相关产品推荐

