我有一个HTML文件,想要在<li>
和</li>
代码之间提取文字。当然有一百万种方法可以做到这一点,但我认为在简单的shell命令中更多地养成这样做的习惯会很有用:
awk '/<li[^>]+><a[^>]+>([^>]+)<\/a>/m' cities.html
问题是,这打印所有而我只是想在括号中打印匹配 - ([^>]+)
- 要么awk不支持,要么我不称职。后者似乎更有可能。如果要将提供的正则表达式应用于文件并仅提取指定的匹配项,您将如何进行?我已经知道了其他六种方式,但我不想让awk
赢得这一轮;)
编辑:数据结构不合理,因此使用位置匹配($1, $2, etc.
)是不行的。
答案 0 :(得分:2)
如果你想在一般情况下这样做,你的列表标签可以包含任何合法的HTML标记,那么awk
是错误的工具。这项工作的正确工具将是一个HTML解析器,您可以信任该解析器以获得HTML解析的所有细节,包括HTML和格式错误的HTML的变体。
如果您针对特殊情况执行此操作,您可以在其中控制HTML格式,那么您可以使awk
为您工作。例如,假设您可以保证每个列表元素永远不会占用多行,始终在同一行上以</li>
终止,从不包含任何标记(例如包含列表的列表),然后您可以使用awk
来执行此操作,但是您需要编写一个完整的awk
程序,该程序首先查找包含列表元素的行,然后使用其他awk
命令来查找您感兴趣的子字符串英寸
但总的来说,awk
是这项工作的错误工具。
答案 1 :(得分:1)
gawk -F'<li>' -v RS='</li>' 'RT{print $NF}' file
对我来说工作得很好。
答案 2 :(得分:0)
我看到了几个问题:
<a>
”到“</a>
”,而不是结束列表项。>
'作为锚点主体的内容;这不是自动错误,但搜索任何不是“<
”或任何不是“$1
”的内容可能更为常见。nawk
”表示第一个字段,其中字段由字段分隔符分隔,默认为空格。sed & awk
中(如1991年'{{1}}'书中所记载的那样)没有适当的机制来从匹配等中提取子字段。目前尚不清楚Awk是否适合这项工作。实际上,正则表达式是这项工作的正确工具并不完全清楚。
答案 3 :(得分:0)
真的不知道awk,Perl怎么样?
tr -d '\012' the.html | perl \
-e '$text = <>;' -e 'while ( length( $text) > 0)' \
-e '{ $text =~ /<li>(.*?)<\/li>(.*)/; $target = $1; $text = $2; print "$target\n" }'
1)从文件中删除换行符,穿过perl
2)使用完整文本初始化变量,开始循环直到文本消失
3)对列表项标签所限定的内容进行“非贪婪”匹配,保存并打印目标,设置为下一遍
有意义吗? (警告,我自己没试过这个代码,需要很快回家......)
P.S。 - “perl -n”是awk(nawk?)模式。 Perl在很大程度上是Awk的超集,所以我从不费心去学习Awk。
答案 4 :(得分:0)
通过您的脚本,如果您可以得到您想要的内容(这意味着<li>
和<a>
标记在一行中。);
$ cat test.html | awk 'sub(/<li[^>]*><a[^>]*>/,"")&&sub(/<\/a>.*/,"")'
或
$ cat test.html | gawk '/<li[^>]*><a[^>]*>(.*?)<\/a>.*/&&$0=gensub(/<li[^>]*><a[^>]*>(.*?)<\/a>.*/,"\\1", 1)'
第一个用于每个awk,第二个用于gnu awk。