sed

sed

ファイルはランダムに見つかるため、場所を覚えておらず、2つのパターン間のテキストを印刷する必要があります。テキストが同じ行に表示されるか、同じ行に表示されない、またはその間に表示されます。

パターンは次<abc>のとおりです。</abc>

例:

aslkdjas<abc>aaaa</abc><abc>bbbb</abc>sdkljasdl<abc>
cccc
dddd</abc>ieurwioeru<abc>eeee</abc>asdasd

2 つのパターン間の値を表示するには、次の出力が必要な場合、またはこのファイルで発生したすべての操作をコンマで区切る必要があります。

aaaa
bbbb
cccc
dddd
eeee

答え1

機能コードを解析するためにテキスト処理ツールを使用しないことをお勧めします。彼らは人間の言語を解析するように設計されており、近いうちに解決できない問題に直面するでしょう。特別なツール(htmlインタプリタ、C ++コンパイラなど)を使用してください。

この場合は、次のことを試すことができますpcregrep

pcregrep -Mo '<abc>\K(.|\n)*?(?=</abc>)' file

明らかにする

aaaa
bbbb

cccc
dddd
eeee

bbbbccccはい、元のファイルに新しい行があったため、との間に新しい行があります。もちろん、必要に応じて空白を削除するために出力をパイプすることもできます(使用trまたは他の方法)sed。しかし、前述したように、実際のケースでは、予期しない結果がより多く発生する可能性があります。

答え2

この単純なケースでは、次のことを試してください。

sed ':L1; N; $bL2; bL1; :L2; s#<abc>#^A#g; s#^[^^A]*^A##; s#</abc>[^^A]*^A#\n#g; s#</abc>.*$##; ' file
aaaa
bbbb

cccc
dddd
eeee

すべての行をパターン空間に収集し、先行パターンをに置き換え、最初に^ABOLを削除し、パターン間^Aの文字列をに置き換え<new line>、EOLまでパターンを削除して印刷します。

答え3

sed

sed ソリューションは、パターンをファイル内の他の場所では使用されない他の 2 文字に変換することです。これは、問題を2つの単一文字間の抽出に関する一般的な問題に置き換えます。

  1. まず、各パターンを単一の文字に変換します。

    sed 'H;$!d;x; s##^A#g;'

    Ctrlそれぞれに - - を入力したと仮定すると、V Ctrl同様のコマンドが入力されました。A^A^B

    最初は、H;$!d;x;パターン空間のファイル全体がキャプチャされます。これは次のことを意味します。

    • すべてのラインを守る
    • パターン空間を消去して最初に戻ります。d
    • もしこれはいいえ最後の行$!
    • 予約済みスペースに保存されているすべての行を取得しますx。 (おそらくgxは、予約されたスペースからパターンスペースにファイル全体がコピーされないため、より少ないメモリが必要です。)
  2. 2 つの単一文字間のパターンを抽出する一般的な手順 (仮説xと励起) は次のとおりです。y

    sedの#^[^x]X##;s#y[^y]$##;s#y[^x]*x#,#g;'

    それは:

    • 最初の()^の前の先頭文字を削除しますx
    • $最後の()の後の文字を削除しますy
    • yとxの間の文字を区切り記号(,この場合はカンマ())に変換します。

すべてを一度に:

$ sed 'H;$!d;x; s#<abc>#^A#g; s#</abc>#^B#g;' s#^[^^A]*^A##; s#^B[^^B]*$##; s#^B[^^A]*^A#,#g;' file
aaaa,bbbb,
cccc
dddd,eeee

grep

(GNU)grepを使用して実行できますが、正しい場所にカンマのみを入力するには、貼り付けの助けが必要です。

$ grep -ozP '(?s)<abc>\K.*?(?=</abc>)' file | paste -zsd ','; echo
aaaa,bbbb,
cccc
dddd,eeee

関連情報