只能使用sed或awk从html页面中提取url的最简单的方法

我想从html文件的定位标记中提取URL。 这需要使用SED / AWK在BASH中完成。 没有perl请。

什么是最简单的方法来做到这一点?

你也可以做这样的事情(假设你已经安装了lynx)…

Lynx版本<2.8.8

lynx -dump -listonly my.html 

Lynx版本> = 2.8.8(礼貌@condit)

 lynx -dump -hiddenlinks=listonly my.html 

你自找的:

 $ wget -O - http://stackoverflow.com | \ grep -o '<a href=['"'"'"][^"'"'"']*['"'"'"]' | \ sed -e 's/^<a href=["'"'"']//' -e 's/["'"'"']$//' 

这是一个粗糙的工具,所以所有关于试图parsing正则expression式的HTML通常的警告适用。

 grep "<a href=" sourcepage.html |sed "s/<a href/\\n<a href/g" |sed 's/\"/\"><\/a>\n/2' |grep href |sort |uniq 
  1. 第一个grep查找包含url的行。 如果你只想看本地页面,你可以添加更多的元素,所以没有http,但相对path。
  2. 第一个sed会在\ n的每个href url标记前添加一个换行符
  3. 第二个sed会缩短每个url之后的第二个“通过用换行符replace它/两个标签两个seds会给你每个url在一行,但有垃圾,所以
  4. 第二个grep href清理混乱
  5. sort和uniq会给你sourcepage.html中每个现有url的一个实例

使用Xidel – HTML / XML数据提取工具 ,可以通过以下方式完成:

 $ xidel --extract "//a/@href" http://example.com/ 

转换为绝对url:

 $ xidel --extract "//a/resolve-uri(@href, base-uri())" http://example.com/ 

一个例子,因为你没有提供任何样本

 awk 'BEGIN{ RS="</a>" IGNORECASE=1 } { for(o=1;o<=NF;o++){ if ( $o ~ /href/){ gsub(/.*href=\042/,"",$o) gsub(/\042.*/,"",$o) print $(o) } } }' index.html 

我对Greg Bacon解决scheme做了一些改动

 cat index.html | grep -o '<a .*href=.*>' | sed -e 's/<a /\n<a /g' | sed -e 's/<a .*href=['"'"'"]//' -e 's/["'"'"'].*$//' -e '/^$/ d' 

这解决了两个问题:

  1. 我们匹配的情况下锚点不是以href作为第一个属性
  2. 我们正在覆盖同一行中有几个锚的可能性

你可以用下面的正则expression式很容易地做到这一点,这是很好findurl:

 \b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))) 

我从John Gruber的关于如何在文本中查找URL的文章中看到它 。

这可以让你find一个文件f.html中的所有URL,如下所示:

 cat f.html | grep -o \ -E '\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))' 

我假设你想从一些HTML文本中提取一个URL,而不是parsingHTML(就像其中一个build议)。 相信与否,有人已经这样做了 。

OT: sed网站有很多很好的信息和许多有趣/疯狂的sed脚本。 你甚至可以在sed 玩 推箱子 !

用第一遍用一个换行符( \n http)代替url(http)的开头。 然后你自己保证,你的链接从行首开始,是行上唯一的URL。

其余的应该很容易,这里是一个例子:

sed "s/http/\nhttp/g" <(curl "http://www.cnn.com") | sed -n "s/\(^http[s]*:[a-Z0-9/.=?_-]*\)\(.*\)/\1/p"

alias lsurls='_(){ sed "s/http/\nhttp/g" "${1}" | sed -n "s/\(^http[s]*:[a-Z0-9/.=?_-]*\)\(.*\)/\1/p"; }; _'

扩展kerkael的答案 :

 grep "<a href=" sourcepage.html |sed "s/<a href/\\n<a href/g" |sed 's/\"/\"><\/a>\n/2' |grep href |sort |uniq # now adding some more |grep -v "<a href=\"#" |grep -v "<a href=\"../" |grep -v "<a href=\"http" 

我添加的第一个grep删除链接到本地​​书签。

第二个删除相关链接到上层。

第三个删除不以http开头的链接。

根据您的具体要求挑选并select其中的哪一个。

你可以试试:

 curl --silent -u "<username>:<password>" http://<NAGIOS_HOST/nagios/cgi-bin/status.cgi|grep 'extinfo.cgi?type=1&host='|grep "status"|awk -F'</A>' '{print $1}'|awk -F"'>" '{print $3"\t"$1}'|sed 's/<\/a>&nbsp;<\/td>//g'| column -c2 -t|awk '{print $1}' 

这就是为什么我试图更好地查看,创buildshell文件并将链接作为参数,它将创buildtemp2.​​txt文件。

 a=$1 lynx -listonly -dump "$a" > temp awk 'FNR > 2 {print$2}' temp > temp2.txt rm temp >sh test.sh http://link.com 

这是我的第一篇文章,所以我尽我所能解释为什么我发布这个答案…

  1. 自从前7个最被投票的答案以来,即使当post明确地说“仅使用sed或awk”时,也包括GREP。
  2. 即使这个post需要“不要perl请”,由于以前的观点,并且在grep里面使用了PERL正则expression式。
  3. 因为这是最简单的方法(据我所知,并且被要求)在BASH中完成。

所以这里来的GNU grep 2.28最简单的脚本:

 grep -Po 'href="\K.*?(?=")' 

关于\K开关,在MAN和INFO页面中没有创build信息,所以我来到这里寻找答案…. \K开关摆脱了以前的字符(和密钥本身)。 请记住man页面的build议:“这是高度实验性的,grep -P可能会警告未实现的function。

当然,你可以修改脚本来满足你的口味或需求,但是我发现它很适合在post中要求的内容,也适用于我们许多人…

我希望人们觉得它非常有用。

谢谢!!!