web-dev-qa-db-ja.com

sedまたはawkのみを使用してhtmlページからURLを抽出する最も簡単な方法

Htmlファイルのアンカータグ内からURLを抽出します。これは、SED/AWKを使用してBASHで実行する必要があります。 Perlは必要ありません。

これを行う最も簡単な方法は何ですか?

55
codaddict

このようなこともできます(lynxがインストールされている場合)...

Lynxバージョン<2.8.8

lynx -dump -listonly my.html

Lynxバージョン> = 2.8.8(@condit提供)

lynx -dump -hiddenlinks=listonly my.html
54
Hardy

あなたはそれを求めた:

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

これは粗雑なツールであるため、正規表現を使用してHTMLを解析しようとすることに関する通常の警告がすべて適用されます。

35
Greg Bacon

Xidel-HTML/XMLデータ抽出ツール を使用すると、これは次の方法で実行できます。

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

絶対URLへの変換:

$ xidel --extract "//a/resolve-uri(@href, base-uri())" http://example.com/
14
Ingo Karkat
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ではなく相対パスを追加できます。
  2. 最初のsedは、各a href urlタグの前に改行を追加し、\ n
  3. 2番目のsedは、行の2番目の "の後の各URLを/ aタグを改行で置き換えることにより短縮します
  4. 2番目のgrep hrefは混乱を解消します
  5. Sortおよびuniqは、sourcepage.htmlに存在する既存の各URLの1つのインスタンスを提供します
14
kerkael

例、サンプルを提供しなかったため

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
12
ghostdog74

Greg Bacon Solutionにいくつかの変更を加えました

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

これにより、2つの問題が修正されます。

  1. アンカーが最初の属性としてhrefで始まっていない場合に一致しています
  2. 同じ行に複数のアンカーがある可能性をカバーしています
9
Crisboot

(コメントの1つが示唆するように)HTMLを解析せずに、いくつかのHTMLテキストからURLを抽出することを想定しています。信じられないかもしれませんが、誰かがすでに 完了 を持っています。

OT: sed website には、lotの良い情報と多くの興味深い/クレイジーなsedスクリプトがあります。 sedでは playSokoban もできます!

5
Alok Singhal

次の正規表現を使用すると、URLを見つけるのに非常に優れています。

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

John Gruberのテキスト内のURLの検索方法に関する記事 から取得しました。

これにより、次のようにファイルf.html内のすべてのURLを見つけることができます。

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

Bashでは、以下が機能するはずです。 sedやawkは使用しませんが、trgrepを使用します。どちらも非常に標準的で、Perlではありません;-)

$ cat source_file.html | tr '"' '\n' | tr "'" '\n' | grep -e '^https://' -e '^http://' -e'^//' | sort | uniq

例えば:

$ curl "https://www.cnn.com" | tr '"' '\n' | tr "'" '\n' | grep -e '^https://' -e '^http://' -e'^//' | sort | uniq

生成する

//s3.amazonaws.com/cnn-sponsored-content
//Twitter.com/cnn
https://us.cnn.com
https://www.cnn.com
https://www.cnn.com/2018/10/27/us/new-york-hudson-river-bodies-identified/index.html\
https://www.cnn.com/2018/11/01/tech/google-employee-walkout-andy-rubin/index.html\
https://www.cnn.com/election/2016/results/exit-polls\
https://www.cnn.com/profiles/frederik-pleitgen\
https://www.facebook.com/cnn
etc...
2
Brad Parks

kerkael's answer の展開:

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は、ローカルブックマークへのリンクを削除します。

2番目は、上位レベルへの相対リンクを削除します。

3番目は、httpで始まらないリンクを削除します。

特定の要件に従って、これらのどれを使用するかを選択します。

1
Nikhil VJ

最初のパスでURLの先頭(http)を改行(_\n_ 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"; }; _'

1
user4401178

それが私が見やすくするために試した方法です。シェルファイルを作成し、パラメーターとしてリンクを指定すると、temp2.​​txtファイルが作成されます。

a=$1

lynx -listonly -dump "$a" > temp

awk 'FNR > 2 {print$2}' temp > temp2.txt

rm temp

>sh test.sh http://link.com
0
Abhishek Gurjar

あなたが試すことができます:

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}'
0
dpathak

これが私の最初の投稿なので、この回答を投稿する理由を説明するために最善を尽くします...

  1. 最初の7つの最も多く投票された回答から、投稿に「sedまたはawkのみを使用する」と明示されている場合でも、4にはGREPが含まれます。
  2. 投稿が「No Perl please」を必要とする場合でさえ、前のポイントのために、そしてgrep内でPerl正規表現を使用するためです。
  3. そして、これはBASHでそれを行うための最も簡単な方法だからです(私が知る限り、必要でした)。

GNU grep 2.28:

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

関して \Kスイッチ、MANおよびINFOページで情報が見つかりませんでしたので、私は here が答えに来ました。..\Kスイッチは、前の文字(およびキー自体)を取り除きます。 manページのアドバイスに従ってください:「これは非常に実験的であり、grep -Pは実装されていない機能について警告する可能性があります。」

もちろん、好みやニーズに合わせてスクリプトを変更することもできますが、投稿でリクエストされたものや、私たちの多くにとって、それは非常にわかりやすいものでした...

皆さんが非常に役立つことを願っています。

ありがとう!!!

0
X00D45