Regex Bash-按模式从HTML中提取URL

Regex Bash-按模式从HTML中提取URL,regex,bash,unix,Regex,Bash,Unix,我有一个Bash脚本,它使用cURL获取一个巨大的HTML,其中包含遵循特定模式的url 模式: https://mycoolsite.com/deliveries/{UUID}.bin 例如: https://mycoolsite.com/deliveries/e4e8c143b2c59f58eb52a03f2cc2d36c4a9fee3b.bin HTML有一行JSON对象列表,如下所示: {"type":"hd_mp4_video",...,&q

我有一个Bash脚本,它使用cURL获取一个巨大的HTML,其中包含遵循特定模式的url

模式:

https://mycoolsite.com/deliveries/{UUID}.bin
例如:

https://mycoolsite.com/deliveries/e4e8c143b2c59f58eb52a03f2cc2d36c4a9fee3b.bin
HTML有一行JSON对象列表,如下所示:

{"type":"hd_mp4_video",...,"container":"mp4"...,{"max_bitrate":290836,...},"url":"https://mycoolsite.com/deliveries/e4e8c143b2c59f58eb52a03f2cc2d36c4a9fee3b.bin","created_at":1556973749,"segment_duration":3,"opt_vbitrate":5625}
存在其他不同“类型”的JSON对象,但我的完整用例是查找hd_mp4_视频

但是,如果我能找到所有匹配该模式的URL,或者如果我能精确地选择第n个匹配的URL,我就可以找到解决方法

我想做一些像

origin_url="https://mycoolsite.com/embed/iframe/2dkmdf59gy"
html=$(curl GET $origin_url)
bin_url=$(#Extract the URL(s))
echo bin_url
您给出的示例“UUID”值似乎只包含数字和小写字符,没有减号作为分隔符,并且正好包含40个字符,因此匹配这些URL的适当POSIX扩展正则表达式应该是:

https://mycoolsite.com/[0-9a-f]{40}.bin
(如果可能存在差异,请查看POSIXextendedregex语法并相应地调整regex。)

因此,您可以使用
sed
实用程序提取它们:

curl "$url" | sed -rn 's_.*(https://mycoolsite.com/[0-9a-f]{40}.bin).*_\1_p'
请注意,我使用的是
\uu
而不是
/
作为sed的
s
命令的分隔符,因为正则表达式包含
/
字符

切换到sed的
r
开关启用扩展正则表达式语法,并且
n
开关告诉sed不要自动打印任何内容

然后,
s
命令末尾的
p
选项显式打印成功进行正则表达式替换的任何行。在本例中,该替换将删除匹配正则表达式前后的任何内容

请注意,虽然这将在输入中打印多个URL,但它不会打印同一行中出现的两个URL,因为我们使用的正则表达式将在一行中的第一个匹配后丢弃任何内容

curl .... | sed -rn '/type:hd_mp4_video/s@(^.*url:)(.*)(,created.*$)@\2@p'

搜索具有类型和hd_mp4_视频的行。根据正则表达式将该行拆分为三个部分,并仅用该行替换第二部分(实际URL),以打印结果。

Perl版本打印整个列表:

curl ... | perl -ne 'map { print("$_\n") } /"url":"([^"]+)/g'

你能演示如何使用提取的html摘要吗?我已经添加了html本身的更多细节。如果这是json,那么使用适当的json解析器,如jq。json本身嵌入在html文本中。可能通过sed将所有内容都当作纯文本处理是最简单的方法,而不是正确地解析。JSON部分可以很好地用于获取mp4的准确URL,但是,在我的例子中,如果我找到了所有可以处理的URL。这是一行摘录吗?谢谢Taylan,非常好的解释。我意识到第一个匹配并不完全是我的用例。我已经更新了询问第n个匹配项的问题或包含所有字符串的列表。有可能调整sed命令来完成吗?我没有得到任何输出。我应该用一些东西替换这个url,还是应该在以后的脚本中将它用作变量?不,除了curl命令之外,不需要修改任何东西