使用 awk 或 sed 删除 < > 之间的所有内容

use*_*786 7 ubuntu sed awk

我在txt文件中有以下内容:

<ol><li><b><a href="/page1/Mark_Yato" title="Mark Yato">Mark Yato</a> ft. MarkAm &amp; <a href="/page1/Giv%C4%93on" title="Giv?on">Giv?on</a> - <a href="/page1/Mark_Yato:Thuieo" title="Mark Yato:Thuieo">Thuieo</a> (7)</b></li>
<li><b><a href="/page1/The_Central" title="The Central">The Central</a> - <a href="/page1/The_Central:AHTIOe oie" title="The Central:AHTIOe oie">AHTIOe oie</a> (7)</b></li>
<li><b><a href="/page1/Taa_Too_A" title="Taa Too A">Taa Too A</a> - <a href="/page1/Taa_Too_A:ryhwtyw w" title="Taa Too A:ryhwtyw w">ryhwtyw w</a> (8)</b></li>
Run Code Online (Sandbox Code Playgroud)

并试图使其输出如下:

Mark Yato ft. MarkAm & Giv?on - Thuieo
The Central - AHTIOe oie
Taa Too A - ryhwtyw w
Run Code Online (Sandbox Code Playgroud)

为了实现这一点,我想我会尝试删除 '<'、'>' 以及它们之间的所有内容,这样就只剩下我想要获取的列表了。

我已经尝试了以下 sed 命令:

sed 's/<[^()]*>//g'
Run Code Online (Sandbox Code Playgroud)

但这只是输出以下内容:

(7)
(7)
(8)
Run Code Online (Sandbox Code Playgroud)

我做错了什么,如果更好地使用它,我该如何修复 sed 命令或将其转换为 awk ?

fra*_*san 25

用正则表达式解析标记是出了名的问题。

虽然您的示例数据不是问题,但尖括号可能会出现在标签属性、注释和其他可能的地方,使得匹配 from<到>不可靠的正则表达式。

您应该求助于实现标记解析器的工具。

例如,将pandoc(版本 >= 2.8)与您的示例数据一起使用(不添加丢失的</ol>标签):

$ pandoc -f html -t plain file 
Mark Yato ft. MarkAm & Giv?on - Thuieo (7)

The Central - AHTIOe oie (7)

Taa Too A - ryhwtyw w (8)
Run Code Online (Sandbox Code Playgroud)

然后,您可以轻松地将此输出作为常规文本进行后处理,以删除空行和其他不需要的部分:

$ pandoc -f html -t plain file |
  sed -e '/^$/d' -e 's/[[:blank:]]*([[:digit:]]*)$//'
Mark Yato ft. MarkAm & Giv?on - Thuieo
The Central - AHTIOe oie
Taa Too A - ryhwtyw w
Run Code Online (Sandbox Code Playgroud)

请注意,在 2.8 版本之前,pandoc用于在生成plain格式输出时将任何强调的文本转换为全大写。<b>您的列表项中的标签会触发此行为(在更改日志或GitHub 上的相关提交中有更多内容)。

根据您的实际输入数据,解决方法可能是使用markdownaspandoc的输入格式,或者明确地:

pandoc -f markdown -t plain file
Run Code Online (Sandbox Code Playgroud)

或隐含地,考虑到它pandoc自动默认为 ( pandoc -t plain file)。


小智 9

你快到了 - 正则表达式匹配是“贪婪的”,所以你需要告诉模式在模式中>不允许结束字符。换句话说,[^()]*模式内的部分将尽可能多地“贪婪”地匹配文本。如果您不告诉模式>从模式的这一部分排除<关闭>,则 Regex 使用的打开和关闭不一定是从 HTML 的角度配对的那些。

改用这个:

sed -e 's/<[^>]*>//g'
Run Code Online (Sandbox Code Playgroud)

这力量正则表达式来删除所有的HTML标签,不是有文字的更大的块<,并>在两端,以及<或者>在中间。


Toa*_*140 6

所以这个命令应该可以解决问题......

sed -i 's/<[^>]*>//g' file
Run Code Online (Sandbox Code Playgroud)

结果文件应该是这个

Mark Yato ft. MarkAm &amp; Giv?on - Thuieo (7)
The Central - AHTIOe oie (7)
Taa Too A - ryhwtyw w (8)
Run Code Online (Sandbox Code Playgroud)

从那里你可以做到这一点

sed -i 's/([0-9])//g' file
Run Code Online (Sandbox Code Playgroud)

它应该为您提供所需的输出

Mark Yato ft. MarkAm &amp; Giv?on - Thuieo
The Central - AHTIOe oie
Taa Too A - ryhwtyw w
Run Code Online (Sandbox Code Playgroud)

编辑:更新第二个命令看起来更整洁。

编辑:替代oneliner

sed -i 's/<[^>]*>//g;s/([0-9])//g' file
Run Code Online (Sandbox Code Playgroud)


Fre*_*ddy 6

您可以使用php剥离所有 HTML 标记并将 HTML 实体转换回正常字符:

$ <file php -r 'echo htmlspecialchars_decode(strip_tags(file_get_contents("php://stdin")), ENT_HTML5);'
Mark Yato ft. MarkAm & Giv?on - Thuieo (7)
The Central - AHTIOe oie (7)
Taa Too A - ryhwtyw w (8)
Run Code Online (Sandbox Code Playgroud)

要另外删除空格(空格、制表符),然后是开头(,然后是一个或多个数字以及以 结尾)的行的结尾sed:

$ <file php -r 'echo htmlspecialchars_decode(strip_tags(file_get_contents("php://stdin")), ENT_HTML5);' |
    sed 's/[[:blank:]]*([[:digit:]][[:digit:]]*)$//'
Mark Yato ft. MarkAm & Giv?on - Thuieo
The Central - AHTIOe oie
Taa Too A - ryhwtyw w
Run Code Online (Sandbox Code Playgroud)