sed 忽略模式并匹配同一行中的模式
sed to ignore a pattern as well as match a pattern in same line
输入文件
<a href="perl.html">perl</a> <a href="http://zoidberg.sourceforge.net/out.html">http://zoidberg.sourceforge.net</a>
<a href="zoiduser.html">zoiduser</a> <a href="perl.html">perl</a> <a href="http://zoidberg.sourceforge.net/sample.html">http://zoidberg.sourceforge.net</a>
我只需要从上面的文件 URL 下面删除 .HTML 扩展名:
<a href="perl.html">perl</a>
<a href="zoiduser.html">zoiduser</a>
这样最终的输出应该是这样的:
<a href="perl">perl</a> <a href="http://zoidberg.sourceforge.net/out.html">http://zoidberg.sourceforge.net</a>
<a href="zoiduser">zoiduser</a> <a href="perl.html">perl</a> <a href="http://zoidberg.sourceforge.net/sample.html">http://zoidberg.sourceforge.net</a>
这就是我正在做的事情:
sed '/"http\|"www\|"mailto/ ! s|\(.html\)||g' file
但它会在匹配第一个模式后立即忽略该行,即避免 URL 以“http|”www|“mailto”开头。
您可以使用
sed -E 's/("(http|www|mailto)[^"]*")|\.html//g' file
详情:
-E
- 启用 POSIX ERE 语法
("(http|www|mailto)[^"]*")
- 第 1 组 (</code>):<code>"
然后是 http
、www
或 mailto
然后是零或 "
以外的更多字符,然后是 "
|
- 或
\.html
- .html
字符串。
替换为第 1 组值。
#!/bin/bash
s='<a href="perl.html">perl</a> <a href="http://zoidberg.sourceforge.net/out.html">http://zoidberg.sourceforge.net</a>
<a href="zoiduser.html">zoiduser</a> <a href="perl.html">perl</a> <a href="http://zoidberg.sourceforge.net/sample.html">http://zoidberg.sourceforge.net</a>'
sed -E 's/("(http|www|mailto)[^"]*")|\.html//g' <<< "$s"
输出:
<a href="perl">perl</a> <a href="http://zoidberg.sourceforge.net/out.html">http://zoidberg.sourceforge.net</a>
<a href="zoiduser">zoiduser</a> <a href="perl">perl</a> <a href="http://zoidberg.sourceforge.net/sample.html">http://zoidberg.sourceforge.net</a>
不建议使用 shell 实用程序(如 sed、awk、perl 等)来解析 HTML。但是如果你真的必须使用某些关键字的否定,那么我建议这样做 perl
:
perl -pe 's/"(?!www|http|mailto)([^"]+)\.html/"/g' f.html
<a href="perl">perl</a> <a href="http://zoidberg.sourceforge.net/out.html">http://zoidberg.sourceforge.net</a>
<a href="zoiduser">zoiduser</a> <a href="perl">perl</a> <a href="http://zoidberg.sourceforge.net/sample.html">http://zoidberg.sourceforge.net</a>
如果这些关键字刚好出现在 "
之后,(?!www|http|mailto)
是使匹配失败的否定前瞻
仅使用您显示的示例,请尝试以下 awk
代码。简单的解释是,检查行中是否包含 <a href="(http|mailto|www):
并且如果此条件为真,则使用 sub
函数首先替换 .html" 出现 ">
然后打印该行,next 将跳过不满足条件的打印行。1
将打印不满足条件的行。
awk '/<a href="(http|mailto|www):/ && sub(/.html">/,"\">"){print;next} 1' Input_file
输入文件
<a href="perl.html">perl</a> <a href="http://zoidberg.sourceforge.net/out.html">http://zoidberg.sourceforge.net</a>
<a href="zoiduser.html">zoiduser</a> <a href="perl.html">perl</a> <a href="http://zoidberg.sourceforge.net/sample.html">http://zoidberg.sourceforge.net</a>
我只需要从上面的文件 URL 下面删除 .HTML 扩展名:
<a href="perl.html">perl</a>
<a href="zoiduser.html">zoiduser</a>
这样最终的输出应该是这样的:
<a href="perl">perl</a> <a href="http://zoidberg.sourceforge.net/out.html">http://zoidberg.sourceforge.net</a>
<a href="zoiduser">zoiduser</a> <a href="perl.html">perl</a> <a href="http://zoidberg.sourceforge.net/sample.html">http://zoidberg.sourceforge.net</a>
这就是我正在做的事情:
sed '/"http\|"www\|"mailto/ ! s|\(.html\)||g' file
但它会在匹配第一个模式后立即忽略该行,即避免 URL 以“http|”www|“mailto”开头。
您可以使用
sed -E 's/("(http|www|mailto)[^"]*")|\.html//g' file
详情:
-E
- 启用 POSIX ERE 语法("(http|www|mailto)[^"]*")
- 第 1 组 (</code>):<code>"
然后是http
、www
或mailto
然后是零或"
以外的更多字符,然后是"
|
- 或\.html
-.html
字符串。
替换为第 1 组值。
#!/bin/bash
s='<a href="perl.html">perl</a> <a href="http://zoidberg.sourceforge.net/out.html">http://zoidberg.sourceforge.net</a>
<a href="zoiduser.html">zoiduser</a> <a href="perl.html">perl</a> <a href="http://zoidberg.sourceforge.net/sample.html">http://zoidberg.sourceforge.net</a>'
sed -E 's/("(http|www|mailto)[^"]*")|\.html//g' <<< "$s"
输出:
<a href="perl">perl</a> <a href="http://zoidberg.sourceforge.net/out.html">http://zoidberg.sourceforge.net</a>
<a href="zoiduser">zoiduser</a> <a href="perl">perl</a> <a href="http://zoidberg.sourceforge.net/sample.html">http://zoidberg.sourceforge.net</a>
不建议使用 shell 实用程序(如 sed、awk、perl 等)来解析 HTML。但是如果你真的必须使用某些关键字的否定,那么我建议这样做 perl
:
perl -pe 's/"(?!www|http|mailto)([^"]+)\.html/"/g' f.html
<a href="perl">perl</a> <a href="http://zoidberg.sourceforge.net/out.html">http://zoidberg.sourceforge.net</a>
<a href="zoiduser">zoiduser</a> <a href="perl">perl</a> <a href="http://zoidberg.sourceforge.net/sample.html">http://zoidberg.sourceforge.net</a>
如果这些关键字刚好出现在 "
之后,(?!www|http|mailto)
是使匹配失败的否定前瞻
仅使用您显示的示例,请尝试以下 awk
代码。简单的解释是,检查行中是否包含 <a href="(http|mailto|www):
并且如果此条件为真,则使用 sub
函数首先替换 .html" 出现 ">
然后打印该行,next 将跳过不满足条件的打印行。1
将打印不满足条件的行。
awk '/<a href="(http|mailto|www):/ && sub(/.html">/,"\">"){print;next} 1' Input_file