コマンドラインで大量のテキストを解析し、すべての(ネストされた)テキスト引用符を空白に置き換える必要があります。引用符は特定の構文で表示されます[quote=username]quoted text[/quote]
。
入れ子になった引用符を含む入力の例は次のとおりです。
text part 1 [quote=foo] outer quote 1 [quote=bar] inner quote [/quote] outer quote 2 [/quote] text part 2 [quote=foo-bar] next quote [/quote] text part 3
予想される出力は次のとおりです。
text part 1 text part 2 text part 3
の助けを借りてこの問題どういうわけか動作させましたが(上記の出力を得ました)、sed ':b; s/\[quote=[^]]*\][^[\/]*\[\/quote\]/ /g; t b'
中間部分( ]には引用符または同じ文字を[^[\/]
含めることができるため問題があります。[
]
つまり、sed
入力がたとえば次のような場合、私のコマンドは機能しません。
text part 1 [quote=foo] outer quote 1 [quote=bar] inner quote [foo] [/quote] outer quote 2 [/quote] text part 2 [quote=foo-bar] next quote [/quote] text part 3
1つの問題は、sed
貪欲な修飾子をサポートしていないようで、可能な限り長い一致が常に入力からキャプチャされることです。扱いにくいㅏ)ユーザー名と雨)一般的な引用。
私はこれがsed
この問題のための最善のツールではなく、そのようなことをすることができないかもしれないと思います。たとえば、おそらく。perl
それともawk
もっとうまくいくでしょうか?
今最後の質問は、この問題を解決するための最良かつ効率的な方法は何ですか?
ベストアンサー1
入力に文字が含まれていないことがわかっている場合は、次のことができます<
。>
sed '
# replace opening quote with <
s|\[quote=[^]]*\]|<|g
# and closing quotes with >
s|\[/quote\]|>|g
:1
# work our way from the inner quotes
s|<[^<>]*>||g
t1'
<
または、文字を含めることができる場合は、>
次のスキームを使用してエスケープできます。
sed '
# escape < and > (and the escaping character _ itself)
s/_/_u/g; s/</_l/g; s/>/_r/g
<code-above>
# undo escaping after the work has been done
s/_r/>/g; s/_l/</g; s/_u/_/g'
AND perl
、再帰正規表現の使用:
perl -pe 's@(\[quote=[^\]]*\](?:(?1)|.)*?\[/quote\])@@g'
またはあなたが言及したように:
perl -pe 's@(\[quote=.*?\](?:(?1)|.)*?\[/quote\])@@g'
を使用すると、perl
オプションを追加して複数行の入力を処理できます-0777
。の場合、sed
コードの前に次のプレフィックスを追加する必要があります。
:0
$!{
N;b0
}
これにより、入力全体がパターン空間にロードされます。