怎么用 bash 的正则表达式从一大堆超链接中筛选中指定的链接?

2021-01-10 13:23:32 +08:00
 gnomeek

请教大佬们一个 regex 的问题。背景是一个只含大量超链接的 html 网页,需要从这些超链接中筛选出指定的链接并下载,大概的代码如下:

wget www.abc.com/result.html
res_url=$something
wget $res_url

result.html 长下面这样:

<a href='www.abc.com/file1'>file1<br/><br/><a href='www.abc.com/file2'>file2<br/><br/><a href='www.abc.com/file3'>file3<br/><br/><a href='www.abc.com/file4'>file4<br/><br/>

res_url 长这样:

www.abc.com/file3

我之前的方法如下:

tmp=$(grep -o "file2.*/file3" result.html)
res_url=$(echo "$tmp" | grep -o "http.*/file3")

但是现在的问题是,这些超链接的顺序是变化的,有可能 file3 的链接下次就在 file2 之前,上面的方法不太稳定。请教各位大佬,怎么使用 shell 的正则表达式来从如下的原始字符串中提取出目标字符串呢?

945 次点击
所在节点    问与答
9 条回复
TimePPT
2021-01-10 13:42:26 +08:00
专业的事交给专业的工具吧,这个需求 lxml 这种 python 解析库几行的事
wd
2021-01-10 13:45:58 +08:00
我看了一会实在看不懂楼主的问题.. 放弃了
gnomeek
2021-01-10 14:19:46 +08:00
@wd hhh- -其实就是一个 jenkins 的 build_result.html,需要写一个脚本来提取出 build 中的一些文件(也就是指定的超链接)
gnomeek
2021-01-10 14:22:49 +08:00
@TimePPT 是的,用 python 会方便很多。不过还是用 bash 解决了- -看来还是不能加班,脑子都快成浆糊了
gnomeek
2021-01-10 14:23:05 +08:00
解决了
```
wget www.abc.com/build_result.html
array=($(grep -ohr -E "https?://[a-zA-Z0-9\.\/_&=@$%?~#-]*" build_result.html))
for element in ${array[@]}
do
if [[ "$element" == *"/file2"* ]]; then
wget $element
fi
done
```
Lax
2021-01-10 14:25:48 +08:00
最好用专业的工具,使用 xpath 或者 css selector 的库去选择对应的元素。

如果非要用正则,就好好看看文档。具体到这里,可以先把全部链接( href )匹配出来,再进行处理。

> grep -i -E -o "href='([^']*file[0-9]*)'"
imn1
2021-01-10 14:26:40 +08:00
问题是你的正则为何这样写?关 file2 什么事?能匹配 href...file3 这段就够了啊
自己搜索一下正则的贪婪、非贪婪
gnomeek
2021-01-10 14:48:01 +08:00
@imn1 但是他们的 prefix 是一模一样,且不确定的。比如会有一些版本号的信息,如 www.abc.com/123/file1.txt 这样,每次的版本号都不一样,没法那么精细的匹配
gnomeek
2021-01-10 14:48:45 +08:00
@Lax 对- -是我脑子没转过来,grep 存成 array,再遍历用 grep 查询 substring 就好了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/743522

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX