一度にラインマッチングとコンテンツ抽出

一度にラインマッチングとコンテンツ抽出

タグ付きの行を見つけ、タグ間の内容を取得したいとh2思います。p

<main>Nothing</main>
<h2>Hello</h2><p>World</p>
<h2>Bells</h2><p>Walls</p>
<h2>Jelly</h2><p>Minus</p>
<p>Fluff</p>

...タブ区切りリストとして:

Hello World
Bells Walls
Jelly Minus

私は現在以下を使用しています:

grep -E "<h2>(.*)<\/h2><p>(.*)<\/p>" | sed -E "s/<h2>(.*)<\/h2><p>(.*)<\/p>/\1 \2/"

grep <pattern>ただし、先にしなければならないというのがちょっと面倒だと思いますsed <the same pattern>。一度だけモードを使用して単一のユーティリティでこれを実行できますか?

ベストアンサー1

XMLパーサーを使用するのは本当に良い考えですが、何らかの理由でパーサーを使用できない場合(ファイル形式が正しくないか、パーサーがインストールされていないなど)、PERLを使用できます。この目的のために:

$ perl -ne 'if(/<h2>(.*?)<\/h2><p>(.*?)<\/p>/){print "$1\t$2\n"}' filename.ext
Hello   World
Bells   Walls
Jelly   Minus

私は予期しない結果が出ないように遅延マッチングを使用することを好みます。

テスト.txt

<h1>Nothing</h1>
<h2>Hello</h2><p>World</p><h2>Goodbye</h2><p>Earth</p>
<h2>Bells</h2><p>Walls</p>
<h2>Jelly</h2><p>Minus</p>
<h3>Zip</h3>

$ perl -ne 'if(/<h2>(.*?)<\/h2><p>(.*?)<\/p>/){print "$1\t$2\n"}' test.txt
Hello   World
Bells   Walls
Jelly   Minus
$ perl -ne 'if(/<h2>(.*)<\/h2><p>(.*)<\/p>/){print "$1\t$2\n"}' test.txt
Hello</h2><p>World</p><h2>Goodbye       Earth
Bells   Walls
Jelly   Minus

ご覧のとおり、正規表現だけではドメイン固有のツールで取得できるものはすべて取得できません。大丈夫なら大丈夫です。入力がパターンと正確に一致しない場合、不正確な結果が生じる可能性があることを覚えておいてください。

おすすめ記事