(((
文字列または文字列の間の段落を削除したい人が誰であるかを知りたいです。)))
Lorem ipsum(((dolor sat amet))), consectetur adipiscing elit. Vestibulum aliquet fringilla est, dictum tempor nunc venenatis at. sed nec velit sat amet velit cursus imperdiet. Vivamustincidunt ut nunc quis euismod。 Quisque sat amet lorem rhoncus, Malesuada justo at, ullamcorpererat.
したがって、「dolor sat amet」は戻り値に表示しないでください。
これが私が今持っているコマンドです。最初のコマンドを検出して停止(((
します。
sed -e "/(((/,/)))/d" file.txt
答え1
sed -e :p -e '/(((/!b
' -e :n -e 's/)))/\
/; s/(((.*\n//; tp
$d;N; s//(((/; tn'
これはトリックを行う必要があります。逃げるb
だろう(それで自動的に印刷されます)一致しないすべての行が見つかったら、そのシーケンスの(((
最初の発生と最初の発生の(((
間のすべての項目を削除しようとします)))
。)))
現在の行で末尾が見つからないために見つからない場合は、拡張N
行を取得して(((
その行と次の行の先頭の間のすべての内容を削除して再検索します。$
検索中に最後の行の終わりに達すると)))
放棄します。これにより、一度に1行以上をバッファリングしなくなります。(((
改行文字を取得する必要があるたびに、後ろのすべての内容が削除されるためです。
1行でできるだけ多くのペアを処理する必要があり、2つの端(((
)))
の間にあるかどうかは重要ではありません。 2より大きく、それ以下の数字を探します。(
)
)
(
一度検出されると、検索)))
にリセットされるため、(((
改行境界を超えた後も次のペアの処理に失敗しません。
:p
-p
分岐タグを宣言します。スクリプトが)))
シーケンスを改行文字に置き換えることができる場合、スクリプトはその位置に分岐し、間(((
のすべての項目を削除します\n
。/(((/!b
b
-away - パターンスペースにシーケンスが残っていない場合は、自動的にパターンスペースを印刷します。(((
:n
- 分岐:
タグを宣言しますn
。(((
aが見つかったが同じ行)))
にaが見つからない場合、スクリプトはここから分岐します。s/)))/\n/
)))
- 改行文字を最初に表示される文字に置き換えます。(((
これは、aがすでに一致している場合にのみ発生します。s/(((.*\n//
(((
- パターンスペースの最初の行と唯一の行の間のすべての内容を置き換えます。\n
tp
-成功した交換が期待されますt
。 trueの場合はラベルに分岐します:p
。$d;N
- 最後の置換が失敗しました。現在の行が$
最後のd
要素の場合、そうでない場合はN
パターンスペースにextを追加します。s//(((/;tn
- 最後の正規表現を繰り返し、(((
最初の項目と今追加した改行の間のすべての項目を置き換え、ラベルに分岐し(((
ます:n
。
答え2
単一行文字列でこれを行うのは非常に簡単です。
sed 's/((([^)]*)))//g' file
複数行の文字列を処理するために必要な場合、より複雑になります。 1つの方法は、すべての改行をtr
NULL文字()に置き換え、\0
置換を実行してから再翻訳することです。
tr '\n' '\0' < file | sed 's/((([^)]*)))//g' | tr '\0' '\n'
または、以下を使用することもできますperl
。
perl -0pe 's/\(\(\([^)]+\)\)\)//g;' file
-0
perl
全ファイルをメモリに読み込む理由(大容量ファイルの場合問題になることがある)は「-p
すべての行を印刷する」という意味です-0
が、以後「行」は実際には全体ファイルです。とs///
同じ考えですsed
。
答え3
努力する
sed 's/((([^)]*)))//' file
または、あなたの文章が良いかもしれません
sed 's/ ((([^)]*)))//' file