我有一个包含以下内容的html页面:
[...]
<tr><td class="n"><a href="play-1.0.1.zip">play-1.0.1.zip</a></td></tr>
<tr><td class="n"><a href="play-1.0.2.1.zip">play-1.0.2.1.zip</a></td></tr>
<tr><td class="n"><a href="play-1.0.2.zip">play-1.0.2.zip</a></td></tr>
[...]
我想提取
play-1.0.1.zip
play-1.0.2.1.zip
play-1.0.2.zip
然后找到最新版本(在这种情况下,它将是play-1.0.2.1.zip)
所以我尝试了
cat tmp.html | grep "<a href=\".*\""
<a href="play-1.0.1.zip">play-1.0.1.zip</a></td><td class="m"
<a href="play-1.0.2.1.zip">play-1.0.2.1.zip</a></td><td class="m"
<a href="play-1.0.2.zip">play-1.0.2.zip</a></td><td class="m"
所以我尝试了懒惰:
cat tmp.html | grep "<a href=\".*?\""
并否定引号
cat tmp.html | grep "<a href=\"[^\"]*?\""
他们两个都没有返回
我只需要获得匹配的部分(不是href),然后找到最新的,但我仍然坚持这个贪婪的问题......
-
非常感谢所有答案,它们都非常有用,很难确定哪一个是正确的,最后我用以下方法解决了这个问题:
grep -v '.*-RC.*' index.html | grep -oP 'play-1.*?.zip' | sort -Vru | head -1
答案 0 :(得分:6)
与其他答案相反,这可以完全用grep完成。
您的输出与输入略有不同 - 显示了额外的元素。出于这个答案的目的,我将使用这个文件:
<tr><td class="n"><a href="play-1.0.1.zip">play-1.0.1.zip</a></td><td class="n"><a href="play-1.0.1.zip">play-1.0.1.zip</a></td></tr>
<tr><td class="n"><a href="play-1.0.2.1.zip">play-1.0.2.1.zip</a></td><td class="n"><a href="play-1.0.1.zip">play-1.0.1.zip</a></td></tr>
<tr><td class="n"><a href="play-1.0.2.zip">play-1.0.2.zip</a></td><td class="n"><a href="play-1.0.1.zip">play-1.0.1.zip</a></td></tr>
这里有一些你需要做的事情。首先,您需要设置正确的grep开关。你需要:
现在你可以使用?修饰符以防止贪婪匹配:
grep -o -P '<a href=".*?"' test.html
<a href="play-1.0.1.zip"
<a href="play-1.0.1.zip"
<a href="play-1.0.2.1.zip"
<a href="play-1.0.1.zip"
<a href="play-1.0.2.zip"
<a href="play-1.0.1.zip"
这不太正确,所以我们将正则表达式锚定到该行的第一个匹配位置:
grep -o -P '^<tr><td class="n"><a href=".*?"' test.html
<tr><td class="n"><a href="play-1.0.1.zip"
<tr><td class="n"><a href="play-1.0.2.1.zip"
<tr><td class="n"><a href="play-1.0.2.zip"
这是正确的数据,但有太多的错误。我们需要使用的是零宽度断言(PCRE语法的一部分)。基本上是正则表达式的一部分,不计入匹配的模式。
grep -o -P '(?<=^<tr><td class="n"><a href=").*?(?=")' test.html
play-1.0.1.zip
play-1.0.2.1.zip
play-1.0.2.zip
现在,您可以执行任何操作以对列表进行排序。有关零宽度断言的更多信息,请参见:http://www.regular-expressions.info/lookaround.html
答案 1 :(得分:5)
使用GNU工具,您可以
grep -oP '(?<=<td class="n"><a href=")[^"]+' | sort -Vr | head -1
答案 2 :(得分:3)
$ grep 'href=' tmp.html | sed 's/.*href="\(.*\)".*/\1/'
play-1.0.1.zip
play-1.0.2.1.zip
play-1.0.2.zip
答案 3 :(得分:3)
没看到剪切(我喜欢它的简洁和速度)所以:
cut -d \“ - f4 tmp.html | sort -Vu | tail -1
输出:
play-1.0.2.1.zip
答案 4 :(得分:2)
使用-E
开关尝试:
piotrekkr@piotrekkr-desktop:~$ echo '<a href="play-1.0.1.zip">play-1.0.1.zip</a></td>' | grep -E '<a href=".*?"'
<a href="play-1.0.1.zip">play-1.0.1.zip</a></td>
答案 5 :(得分:1)
grep
似乎不是正确的工具,因为您想要提取子匹配。
这是一个可以做到的perl单行:
$ perl -ne 'while(/<a href="([^"]+)"/g){print $1, "\n";}' input
play-1.0.1.zip
play-1.0.2.1.zip
play-1.0.2.zip
答案 6 :(得分:1)
使用 Craig Andrews 提供的答案并添加OSX支持。
grep -o -P '(?<=^<tr><td class="n"><a href=").*?(?=")' /test.html | sort -n -r -k1.10,12
结果:
play-1.0.2.1.zip
play-1.0.2.zip
play-1.0.1.zip
答案 7 :(得分:0)
如果您知道字段编号,Awk是一个很棒的工具:
awk -F\" '$4 ~ /play.*zip/{ print $4 }'
或者这是一种混乱的方式;搜索所有zip文件:
cat file | tr '"' '\n' | grep -e '.zip$' | sort -u
这将为您获取所有zip文件。 tr实用程序未得到充分利用,它只是替换了一个字符,在这种情况下用换行符替换每个双引号,很好地在自己的行上获取引用数据,你可以在其中进行grep。排序-u避免了重复。
答案 8 :(得分:0)
perl方式:
cat thefile | perl -anF'"' -e 'print $F[3],"\n";($v)=$F[3]=~/(\d.*\d)/;$m=$v if$v gt $m;}{print "max=$m\n";'
<强>输出:强>
play-1.0.1.zip
play-1.0.2.1.zip
play-1.0.2.zip
max=1.0.2.1