web-dev-qa-db-ja.com

ファイル内の複数の行を単一のWordに置き換えるにはどうすればよいですか?

filenameファイルの内容は次のとおりです(例)。

My block of line starts from here 
START
First line
second line
third line
END
and end to here for example.

STARTENDの間の行ブロックを、たとえばSINGLEWORDなどの単一のWordに置き換えたい。以下のように:

My block of line starts from here 
SINGLEWORD
and end to here for example.

次のコマンドを使用して、行のブロックを見つけることができます。

grep -Pzo "START(.|\n)*END" filename

上記のコマンドを実行した結果は次のようになります。

START
First line
second line
third line
END

次に、このコマンドを使用して、すべての行を1行に結合しました。

LAST_RESULT | sed -e :a -e '/$/N; s/\n/ /; ta'

次に、この結果を取得します。

START First line second line third line END

そして、最後のコマンドLAST_RESULTS | sed 's/.*/SINGLEWORD/'でそれらを"SINGLEWORD"に変更すると、この結果が得られます。

SINGLEWORD

今私が欲しいのは、どうすればこのコマンド(またはあなたの提案コマンド)を使用し、行のブロックを(SINGLEWORD)単語に置き換えることができますか?そして、最終的な結果は次のファイルのようになります。

My block of line starts from here 
SINGLEWORD
and end to here for example.
8
αғsнιη

これはPerlで非常に簡単に実行できます。

$ Perl -i -p0e 's/START.*?END/SINGLEWORD/s' file
$ cat file
My block of line starts from here 
SINGLEWORD
and end to here for example. 

説明

-0は行区切り文字をnullに設定します

-pは、-eで指定されたスクリプトを各行に適用し、その行を出力します

正規表現修飾子:

  • /s文字列を1行として扱います。つまり、.を変更して、通常は一致しない任意の文字(改行でも)に一致するようにします。

なぜ?

  • デフォルトでは、定量化されたサブパターンは「貪欲」です。つまり、パターンの残りの部分を一致させながら、特定の開始位置を指定してできるだけ多く一致します。可能な最小回数に一致させるには、数量詞の後に?を付けます。
12
Sylvain Pineau

Perlpythonなどがなくてもこれが可能かどうか疑問に思っていました。そして、私はsedを使用してこのソリューションを見つけました:

$ sed ':a;N;$!ba;s/START.*END/SINGLEWORD/g' filename

説明:

  1. :aラベル「a」を作成
  2. N次の行をパターンスペースに追加する
  3. $!最後の行ではない場合babranch(go to)label 'a'
  4. ssubstitute/START.*END/ by SINGLEWORD/ gグローバルマッチ(可能な限り)

見つかった ここ

@ KasiyA、たくさんの興味深いことを学んでくれてありがとう!

13
c0rp