パターンを含む行の前に新しい行を追加する必要があります。パターンは常に現在行の最初の文字列であると仮定できます。例えば
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つの機能があります。-i
awk
-i /usr/share/awk/inplace.awk
^使用しないでください-i inplace
現在の作業ディレクトリから最初に拡張機能をgawk
ロードしようとすると、誰かがそのディレクトリにマルウェアを植えた可能性があります。システムに付属の拡張プログラムのパスは異なる場合があります。出力を参照してください。inplace
inplace
inplace.awk
inplace
gawk
gawk '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
これでgrep
forを実行すると、前のbar
行は空でなければなりません。
if [[ $(grep -B 1 'bar' infile | head -1) == "" ]]; then echo "line is empty"; fi
line is empty
grep
on を使用するのとは対照的に、前の行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
拡張子を含む正規表現