前の行がすでに空でない限り、パターンに一致する各行の前に改行文字を挿入します。

前の行がすでに空でない限り、パターンに一致する各行の前に改行文字を挿入します。

パターンを含む行の前に新しい行を追加する必要があります。パターンは常に現在行の最初の文字列であると仮定できます。例えば

This is a
pattern
This is a
pattern

sed次のコマンドを使用して新しい行を追加できます。

sed -i 's/pattern\+/\n&/g' file

出力を得る

This is a

pattern
This is a

pattern

複数の新しい行が追加されるのを防ぐために(複数回実行する場合)、パターンの前の行が空であることを確認したいと思います。私はこれができることを知っています

if [ "$line" == "" ]; then

しかし、最初にパターンに一致する前の行をどのように決定しますか?

編集:パターンが複数回表示されることがあります。

答え1

前の行を予約済みスペースに保存できます。

sed '
 /^pattern/{
   x
   /./ {
     x
     s/^/\
/
     x
   }
   x
 }
 h'

しかし、より明確になりますawk

awk '!previous_empty && /pattern/ {print ""}
     {previous_empty = $0 == ""; print}'

GNU実装に内部編集オプションがsedあるように、GNU実装には1つの機能があります。-iawk-i /usr/share/awk/inplace.awk


^使用しないでください-i inplace現在の作業ディレクトリから最初に拡張機能をgawkロードしようとすると、誰かがそのディレクトリにマルウェアを植えた可能性があります。システムに付属の拡張プログラムのパスは異なる場合があります。出力を参照してください。inplaceinplaceinplace.awkinplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'

答え2

あなたの質問は元のsedに関するものであることを知っていますが、vimには非常に簡単な答えがあります。

:g/.\npattern/norm o

または、コマンドラインから完全に実行したい場合:

vim file -c "g/.\npattern/norm o" -c "wq"

どのように機能するかは、次の正規表現に一致する行を見つけることです。

.\npattern

これは、パターンに従う空白ではなく行です。次に、各一致に対してnorm o現在のカーソル位置の下に改行文字を開く次のコマンドを適用します。

答え3

しかし、最初にパターンに一致する前の行をどのように決定しますか?

うーん…おそらくこれが食べられると思います。

使用grep-B切り替え:

 -B num, --before-context=num
         Print num lines of leading context before each match.  See
         also the -A and -C options.

次のファイルを検討してください。

cat infile 
foo

bar
baz

これでgrepforを実行すると、前のbar行は空でなければなりません。

if [[ $(grep -B 1 'bar' infile | head -1) == "" ]]; then echo "line is empty"; fi
line is empty

grepon を使用するのとは対照的に、前の行bazは次のようになります。いいえ空:

if [[ $(grep -B 1 'baz' infile | head -1) == "" ]]; then echo "line is empty"; fi
<no output>

答え4

gnusを使用した場合(Linuxや他の多くのシステムではデフォルトであり、誰でも利用可能です)

sed -zri  's/([^\n]\n)(pattern)/\1\n\2/g' file

どこ

  • ([^\n]\n)(pattern)空でない行以降のパターン
  • -zヌル文字で「行」を区切ります(スラフファイル)。
  • -r拡張子を含む正規表現

関連情報