我在txt文件中有以下内容:
<ol><li><b><a href="/page1/Mark_Yato" title="Mark Yato">Mark Yato</a> ft. MarkAm & <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标签,不是有文字的更大的块<,并>在两端,以及<或者>在中间。
所以这个命令应该可以解决问题......
sed -i 's/<[^>]*>//g' file
Run Code Online (Sandbox Code Playgroud)
结果文件应该是这个
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 -i 's/([0-9])//g' file
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)
编辑:更新第二个命令看起来更整洁。
编辑:替代oneliner
sed -i 's/<[^>]*>//g;s/([0-9])//g' file
Run Code Online (Sandbox Code Playgroud)
您可以使用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)