タグ付きの行を見つけ、タグ間の内容を取得したいと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
ご覧のとおり、正規表現だけではドメイン固有のツールで取得できるものはすべて取得できません。大丈夫なら大丈夫です。入力がパターンと正確に一致しない場合、不正確な結果が生じる可能性があることを覚えておいてください。
答え2
正しい方法は次のようにすることです。xmlstarlet
ツール(xml / htmlデータ解析用):
xmlstarlet sel -t -m '//h2' -v 'concat(., "'$'\t''", ./following-sibling::p)' -n file
出力:
Hello World
Bells Walls
Jelly Minus
答え3
引用符で囲まれていない正規表現を含めるために使用する正規表現の場合は、正規表現構文を()
拡張する必要があります(またはそれぞれ、およびをおよびに(
置き換える)
必要\(
があります\)
)。これはとても簡単です。
[^<]
また、ポイントの代わりに貪欲なマッチを使用しすぎないようにすることもできます。
もちろん、変数を設定して引用符を使用して実行できます。ただsed:
$ a='<h2>([^<]*)<\/h2><p>([^<]*)<\/p>'
$ sed -nE '/'"$a"'/s/'"$a"'/\1 \2/p' infile
しかし、これが単純化できるため、より良くなります。 Sedは最後に使用された正規表現を覚えているので、左s//
(空)で十分です。
$ sed -nE '/'"$a"'/s//\1 \2/p' infile
または変数なし:
$ sed -nE '/<h2>([^<]*)<\/h2><p>([^<]*)<\/p>/s//\1 \2/p' infile
Hello World
Bells Walls
Jelly Minus
答え4
考えられる解決策は次のとおりですsed
。
sed 's/<[^13>]*>/ /g' test | sed 's/<h[13]>.*<\/h[13]>//' <file>
Hello World
Bells Walls
Jelly Minus
第二に、不要なタグsed
を削除してください。<h1>
<h3>
パターン説明:
/<[^13>]*>/ /
- 任意の記号で*
始まり<
終わるテキストを検索します>
。ただし、ラベル間の記号1
または3
必然ではない(^
)出席する。