file1
たとえば、次のような入力ファイルがあります。
WRITE=2
START=1
SMEAR=0
MIN=6
MAX=100
私の問題は文字列を検索し、SMEAR
文字列が存在する場合は行全体をSMEAR=-5
。ただしSMEAR
、存在しない場合は新しい行を挿入する必要がありますSMEAR=-5
。最終的にこの行はSMEAR=-5
一度だけ現れなければなりません。 sed を使用して文字列を置き換えることができます。
sed -i '/SMEAR/c\SMEAR=-5' file1
あるいは、文字列を新しい行に挿入することもできます。
sed -i '10i SMEAR=-5' file1
しかし、ファイルに存在する文字列に基づいて文字列をどのように結合できますか?
編集する:SMEAR
値を変数として渡すことができれば役立ちます。
答え1
ユースケースでは、行の順序は重要ではないようです。これを考えると、ex
単に以下を使用します。
SMEAR
次のすべてのインスタンスを削除します。- 目的の行を挿入してください。
次のことができます。
printf '%s\n' 'g/SMEAR/d' '$a' 'SMEAR=-5' . x | ex file.txt
最初のコマンドは、正規表現に一致するすべての行をg
完全に削除します。d
/SMEAR/
次のコマンドは、a
最後の行()の$
後に行を追加することですSMEAR=-5
。追加するテキストの終わりです.
。
このx
コマンドは変更を保存して終了します。
各コマンドは改行文字で終わり、printf '%s\n'
それを使用してに送信しますex
。
また見てくださいこの非常に類似したソリューションこれは私がしばらく前にvi / Vim Stack Exchangeに書いたものです。
変更を保存せずに変更されたファイルをコマンドラインに印刷して変更をテストするには、次の2つのx
コマンドを置き換えます。%p 'q!'
printf '%s\n' 'g/SMEAR/d' '$a' 'SMEAR=-5' . %p 'q!' | ex file.txt
%
「フルバッファ」を意味し、これがp
印刷されます。
q!
「やめる、変化をあきらめる」という意味だ。
変更を次に保存します。新しい%p
ファイルを次のように置き換えますw newfile.txt
。
printf '%s\n' 'g/SMEAR/d' '$a' 'SMEAR=-5' . 'w newfile.txt' 'q!' | ex file.txt
これにより、w
変更されたバッファが作成されますnewfile.txt
。
または、次のように最初からこれを実行してバックアップを作成し、変更したファイルの内容を元の場所に保存することもできますfile.txt
。
printf '%s\n' 'w file.txt.bak' 'g/SMEAR/d' '$a' 'SMEAR=-5' . x | ex file.txt
編集する:実際に使用する必要はありませんq!
。省略するだけでx
変更の保存を避けることができます。ex
追加の入力を読み取ろうとしたときにEOFが受信されると、変更を保存せずに終了します。
答え2
h
試してみてください。行が一致したら、前のスペースにコピーしてs
値を変更します。
緯度線の$
保持空間とパターン空間を変更し、x
後者が空であることを確認します。空でない場合は、すでに交換が完了していることを意味しますので、別の措置を講じる必要はありません。空の場合、一致する項目がないことを意味するため、パターン空間が置き換えられ、保持SMEAR=-5
バッファの現在の行に追加されます。最後に、eはx
再び変更されます。
sed '/SMEAR/{h;s/.*/SMEAR=-5/};${x;/^$/{s//SMEAR=-5/;H};x}' infile
上記はgnu sed
構文です。持ち運べる:
sed '/SMEAR/{
h
s/.*/SMEAR=-5/
}
${
x
/^$/{
s//SMEAR=-5/
H
}
x
}' infile
代替方法ed
:
ed -s infile<<\IN || printf %s\\n SMEAR=-5 >> infile
/SMEAR.*/s//SMEAR=-5/
w
q
IN
パターンに一致する行がないとed
エラーが発生するため、printf...
2番目のコマンド()が実行され、その行がファイルに追加されます。それ以外の場合、ed
ファイルはその場所で編集されます。
SMEAR
次の変数に値を保存すると、
var=-7
次を実行します。
sed '/SMEAR/{h;s/.*/SMEAR='"$var"'/};${x;/^$/{s//SMEAR='"$var"'/;H};x}' infile
または
ed -s infile<<IN || printf %s\\n "SMEAR=${var}" >> infile
/SMEAR.*/s//SMEAR=${var}/
w
q
IN
答え3
または実装ワイルドカードのアイデア
(含まれているすべての既存の行を削除し、目的のSMEAR
行を挿入します。)石器時代ツールを使用する:
(grep -v '^SMEAR=' file1; echo 'SMEAR=-5') > file1.tmp && cp file1.tmp file1 && rm file1.tmp
または、保存された属性(権限など)やハードリンクに興味がない場合は、file1
次のことを実行できます。
(grep -v '^SMEAR=' file1; echo 'SMEAR=-5') > file1.tmp && mv file1.tmp file1
または があればこれを行うsponge
ことができます。
(grep -v '^SMEAR=' file1; echo 'SMEAR=-5') | sponge file1