複数行のテキストファイル内のネストされた中括弧の間のすべてのテキストを削除するにはどうすればよいですか?


9

この質問は、複数行のテキストファイルで、中かっこの間のすべてのテキストを削除するには どうすればよいですか。(まったく同じですが、ネストの要件はありません)。

例:

This is {
{the multiline
text} file }
that wants
{ to {be
changed}
} anyway.

になるはずです:

This is 
that wants
 anyway.

ある種の1行のbashコマンド(awk、sed、perl、grep、cut、tr ...など)でこれを行うことは可能ですか?

回答:


13
$ sed ':again;$!N;$!b again; :b; s/{[^{}]*}//g; t b' file3
This is 
that wants
 anyway.

説明:

  • :again;$!N;$!b again

    これにより、ファイル全体が読み込まれます。

    :againラベルです。 N次の行を$!N読み取り、まだ最後の行にいないという条件で次の行を読み取ります。 これが最後の行ではないという条件でラベルに$!b again戻りagainます。

  • :b

    これはラベルを定義しbます。

  • s/{[^{}]*}//g

    これにより、テキストに中括弧が含まれていない限り、中括弧内のテキストが削除されます。

  • t b

    上記の代替コマンドによって変更が生じた場合は、labelに戻りbます。このように、すべてのブレースグループが削除されるまで、代替コマンドが繰り返されます。


3

Perlのアプローチ:

$ perl -F"" -a00ne 'for (@F){$i++ if /{/; $i||print; $i-- if /}/}' file
This is 
that wants
 anyway

説明

  • -a:配列に指定さ-Fれたファイル区切り文字の自動分割をオンにします@F
  • -F"":入力フィールド区切り文字を空に設定します。これにより、各要素が@F入力文字の1つになります。
  • -00:「段落モード」をオンにします。「行」は、2つの連続する改行文字として定義されます。つまり、この場合、ファイル全体が1行として扱われます。ファイルに多くの段落を含めることができ、ブラケットが複数の段落にまたがることがある場合は、-0777代わりに使用してください。
  • -ne:入力ファイルを読み取り、指定されたスクリプトを各行に適用します-e

スクリプト自体は実際には非常に単純です。カウンタは、a {が表示されるたびに1ずつ増加し、ごとに1ずつ減少し}ます。これは、カウンターが0の場合、角かっこ内にいないため、次のように出力する必要があることを意味します。

  • for (@F){}@F行の各文字、の各要素に対してこれを行います。
  • $i++ if /{/;$iこの文字がaの場合、1 ずつ増加する{
  • $i||print;$iが設定されていない限り印刷します(0は未設定としてカウントされます)。
  • $i-- if /}/$iこの文字が}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.