2つのタグ間のテキスト


23

これら2つのタグの間にあるものはすべて<tr> </tr>、HTMLドキュメントから取得したいです。現在、HTMLパーサーを保証する特定のHTML要件はありません。私は単に一致<tr></tr>、その間にすべてを取得するものが必要であり、複数trのものが存在する可能性があります。私はawkを試しましたが、それはうまくいきますが、何らかの理由で抽出された各行の複製を与えることになります。

awk '
/<TR/{p=1; s=$0}
p && /<\/TR>/{print $0 FS s; s=""; p=0}
p' htmlfile> newfile

これについてどうやって行くのですか?


IIUCのawkスクリプトは次のとおり'/<tr/{p=1}; p; /<\/tr>/{p=0}'です。動作しない場合は、入力例と期待される出力を投稿してください。
トール

あなたawkが働いているが、重複を与えているので、awkの出力を渡しsort -uて明確にして
ください-igiannak

回答:


14

...すべてを<tr>...</tr>したい場合:

grep -o '<tr>.*</tr>' HTMLFILE | sed 's/\(<tr>\|<\/tr>\)//g' > NEWFILE

複数行の場合:

tr "\n" "|" < HTMLFILE | grep -o '<tr>.*</tr>' | sed 's/\(<tr>\|<\/tr>\)//g;s/|/\n/g' > NEWFILE

文字「|」の最初のHTMLFILEを確認します (通常ではありませんが可能です)、存在する場合は、存在しないものに変更します。


1
これは、開始タグと終了タグが同じ行にある場合にのみ機能します。
l0b0

echo "bla<tr>foo</tr>bla<tr>bar</tr>bla" | grep -o '<tr>.*</tr>' | sed 's/\(<tr>\|<\/tr>\)//g'与えるfooblabarblaそこにすべきではありませんか?
NN

@ l0b0正しい。複数行の互換1 ...のために行くだろう
xx4h

grep -Po '<tr>.*?</tr>'@NNの場合、1行に1つの結果が返されますが、移植性はありません。
l0b0

「specs」または「spec-style」の意味がわかりませんが、Webブラウザーはhtmlパーサー使用し、htmlパーサーはどのように記述されていてもhtmlを解析します。htmlではないものは解析されませんが、ブラウザーも解析されないため、パーサーが解析できない「html」を記述することはありません。言い換えれば、まともなパーサがある絶対に確かにこれを行うための最善の策。
goldilocks

11

HTMLパーサーを保証する要件があります:HTMLを解析する必要があります。PerlのHTML :: TreeBuilder、PythonのBeautifulSoupなどは使いやすく、複雑で脆弱な正規表現を書くよりも簡単です。

perl -MHTML::TreeBuilder -le '
    $html = HTML::TreeBuilder->new_from_file($ARGV[0]) or die $!;
    foreach ($html->look_down(_tag => "tr")) {
        print map {$_->as_HTML()} $_->content_list();
    }
' input.html

または

python -c 'if True:
    import sys, BeautifulSoup
    html = BeautifulSoup.BeautifulSoup(open(sys.argv[1]).read())
    for tr in html.findAll("tr"):
        print "".join(tr.contents)
' input.html

9

sedそして、awkよくこの作業には適していない、あなたではなく、適切なHTMLパーサを使用する必要があります。たとえばhxselect、w3.orgから:

<htmlfile hxselect -s '\n' -c 'tr'

hxselectが最良の選択かどうかはわかりません。私はそれを使用していません、マニュアルページには、「整形式のXMLドキュメントを読む」と書かれていますが、多くのhtmlドキュメントはそうではありません。おそらく試してみる価値があります。perl、pythonなどで利用可能なHTMLパーサーライブラリ。等 それがオプションであれば、はるかに良いでしょう。
goldilocks

2
@goldilocks:最良の選択は状況に依存します。私の経験でhxselectは、整形式のhtml / xmlドキュメントでかなり良い仕事をしています。また、perlやpythonなどよりも高速に使用できます。/ とパーサーライブラリのhxselect間の良い中間点だと思います。sedawk
トール

1
うまくいけばそれは素晴らしいことです!TechJackに警告を追加していましたが、そうしなかった場合-何らかの種類のパーサーを使用することも推奨していたためです。
goldilocks

トール、よさhxselectそうだ、間違いなくそれをもっと探検します。ありがとう。
TechJack

@goldilocks:hxnormalize整形式でないhtml / xmlファイルを処理します。
トックランド

5

ruby利用可能な場合は、次のことができます

ruby -e 'puts readlines.join[/(?<=<tr>).+(?=<\/tr>)/m].gsub(/<\/?tr>/, "")' file

file入力htmlファイルはどこにありますか。このコマンドは、Rubyのワンライナーを実行します。まず、すべての行を読み取りfile、文字列に結合しますreadlines.join。次に、文字列からそれは間(は含まない)ものを選択<tr>して<\/tr>、それは関係なく、改行の1文字以上です[/(?<=<tr>).+(?=<\/tr>)/m]。次に、文字列から<tr>または</tr>を削除しますgsub(/<\/?tr>/, "")(ネストされたtrタグを処理するために必要です)。最後に、文字列を出力しますputs

あなたは、HTMLパーサがあなたのために保証されていませんが、それは非常に使いやすいと言わ鋸山をしてruby、それがコマンド簡単になります。

ruby -rnokogiri -e 'puts Nokogiri::HTML(readlines.join).xpath("//tr").map { |e| e.content }' file

-rnokogiriのこぎりをロードします。Nokogiri::HTML(readlines.join)のすべての行を読み取りますfilexpath("//tr")すべてのアウトピックtr要素とmap { |e| e.content }の間で何の各要素の内容アウトピック、すなわち<tr></tr>


1

grep

tr複数行にわたってタグ内のコンテンツを取得するには、xargs最初にそれを渡します。次に例を示します。

curl -sL https://www.iana.org/ | xargs | egrep -o "<tr>.*?</tr>"

内部HTMLのみを返すには、次を使用します。

curl -sL https://www.iana.org/ | xargs | grep -Po "<tr>\K(.*?)</tr>" | sed "s/..tr.//g"

perlre拡張パターンの構文を確認してください。

注:パフォーマンスを高速化するために、ripgrepどちらの構文が似ているかを検討できます。


xargsを使用せずに見栄えが良くなり、egrep -o "<script。*?</ script>"を使用してインラインjavascriptを見つけるのに便利になりました
Andrew

0

pup

使用例pupCSSセレクターを使用):

pup -f myfile.html tr

タグなしのテキストのみを印刷するには、次を使用しますpup -f myfile.html tr text{}

以下にいくつかの例を示しcurlます。

curl -sL https://www.iana.org/ | pup tr text{}
pup -f <(curl -sL https://www.iana.org/) tr text{}

xpup

xpupHTML / XML解析(XPathをサポート)の使用例:

xpup -f myfile.html "//tr"

0

の簡単なリストである場合、<tr>これは役立ちます:

perl -ne 'print if /<tr>/../</tr>/' your.html > TRs.log

乾杯

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.