如何在Linux上搜索和替换多个文件中的长HTML



我需要递归地找到所有具有以下HTML:的文件

<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>
<meta charset="utf-8">
<meta name="google" value="notranslate">

并将其替换为以下HTML:

<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>
<meta charset="utf-8">
<meta name="google" value="notranslate">
<meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="date=no">
<meta name="format-detection" content="address=no">
<meta name="format-detection" content="email=no">

这是我尝试通过管道将grep命令发送到sed时失败的一次尝试:

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 -i@ sed -i 's/<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>n    <meta charset="utf-8">n    <meta name="google" value="notranslate">n/<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>n    <meta charset="utf-8">n    <meta name="google" value="notranslate">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' @

仅grep命令就可以完美工作。

为了清楚起见,以下是分为多个部分的命令

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 -i@ sed -i 's/<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>
n    <meta charset="utf-8">
n    <meta name="google" value="notranslate">
n
/<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>
n    <meta charset="utf-8">
n    <meta name="google" value="notranslate">
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,而不需要以前的grepxargs。通常,使用sed对文件进行的内联编辑看起来像:

sed -i 's/TO_FIND/REPLACE/' FILE.txt

另一条评论是,sed不是一个编辑HTML的好工具。查看RegEx匹配的开放标记(XHTML自包含标记除外)。

话虽如此,我提出这个剧本是为了满足你的要求。

#!/bin/bash
#
find . -type f -name "*.html" -print0 | while IFS= read -r -d '' file
do
if [[ $(grep -c 'id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"' $file) -ne 0 ]]
then
# Add the content...
echo "Adding in file $file"
sed -i 's#</head>#    <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    </head>#' "$file"
else
echo "Nothing to do on $file"
fi
done
  • findwhileread一起使用涵盖了在子目录中有HTML文件的情况
  • grep已经被高度简化。如果存在id和类值,则足以识别有效文件
  • 然后在sed中,您可以添加新行。您的sed用这些相同的行替换了行
  • 我在sed中使用了#作为分隔符,而不是/,以避免与HTML代码混淆
  • 这是基于我自己创建的一个文件,因为您没有提供示例。你应该在问题中提供样本
  • <head>部分中标记的顺序是不相关的,因此在关闭</head>之前添加行是可行的
  • 显然,else部分是可选的
  • <opinion>我发现这种类型的脚本在未来比长的单行更容易理解和调试。</opinion>

假设index.html是:

<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>
<meta charset="utf-8">
<meta name="google" value="notranslate">
<title>TITRE</title>
</head>
<body>
<p>PARAGRAPH</p>
</body>
</html>

结果是:

<html id="blx-5fb3c619e82a2863d6567c52-000000001" class="blx-5fb3c619e82a2863d6567c52"><head>
<meta charset="utf-8">
<meta name="google" value="notranslate">
<title>TITRE</title>
<meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="date=no">
<meta name="format-detection" content="address=no">
<meta name="format-detection" content="email=no">
</head>
<body>
<p>PARAGRAPH</p>
</body>
</html>