2017-05-14 7 views
0

sedについてよく知らないが、パターンの前に2行(タイムアウト値と空行)を削除してから、両方の行を更新タイムアウトで再挿入しようとしている。sedを使用して特定のパターンの前に2行を削除する

- id: phase1 
    blahblahbal 
    timeout: 720 

- id: phase2 
    blahblahbalh 
    timeout: 1800 

私は「900」への最初のタイムアウトを更新しようとしている:

は、ここで私がしましたYAMLファイルの一部です。ここで

は、私はgrepをしてきたものだ:

grep -v "$(grep -B 2 'id: phase2' test.yaml | grep -v 'id: phase2')" test.yaml > test.yaml 

、その後、SEDで更新された値を挿入します。これは動作していますが、grepはうまく見えません。パターンの前にsedで2行を削除する方法はありますか?

- id: phase1 
    blahblahbal 
- id: phase2 
    blahblahbalh 
    timeout: 1800 

予想される出力の最終:

- id: phase1 
    blahblahbal 
    timeout: 900 

- id: phase2 
    blahblahbalh 
    timeout: 1800 
+0

あなたの予想される出力を表示します。 – 123

+0

パターンに対する相対的な削除は困難です。削除する必要のあるパターンにパターンが従うと、重複します。 –

+0

@JonathanLefflerこのコメントはどのように役に立ちますか? – 123

答えて

1

これは、それがAWK(back-replace2.awk)を使用して行うことができる方法である:

$1 ~ /timeout:/ { lineTimeOut = NR } 
/^[ \t\r]*$/ { lineEmpty = NR } 
/- id: phase2/ { 
    if (lineTimeOut == NR - 2 && lineEmpty == NR - 1) { 
    buf1 = " timeout: 900" 
    } 
} 
{ 
    if (NR > 2) { print buf1 } 
    buf1 = buf2 ; buf2 = $0 
} 
END { 
    if (NR >= 2) { print buf1 } 
    if (NR >= 1) { print buf2 } 
} 

最初のsed/grepの後に出力期待

timeout:行の行番号と空行が記憶されています。従って、これらの線が、注目されたパターン(ここでは- id: phase2)が一致する線の直前/直前の2行に現れたかどうかを確認することができる。

変数buf1およびbuf2は、ある種のサイクルバッファリング(つまり、3番目の最後の行がすべての行にエコーされます)を行うために使用されます。

したがって、残りの入力(サイクルバッファの内容)をエコーするには、ENDのルールが必要です。

試験:

$ cat >back-replace2.txt <<EOF 
- id: phase1 
    blahblahbal 
    timeout: 720 

- id: phase2 
    blahblahbalh 
    timeout: 1800 
EOF 

$ awk -f back-replace2.awk back-replace2.txt 
- id: phase1 
    blahblahbal 
    timeout: 900 

- id: phase2 
    blahblahbalh 
    timeout: 1800 

$ 

  1. Iは、エッジケース(例えば、3未満の線を有するファイルが正しく処理されているかどうか)を確認しませんでした。

  2. パターンマッチングと置換は、追加ロジックが必要な場合があります。質問者がスクリプトを適切に調整できると確信しています。ここで

+0

ありがとう@Scheff。私は別の方法も見つけました(答えとして追加されました)。 – Junaid

1

はSEDと私のソリューションです:

# Remove above two lines before phase2 id 
sed -i ':a;N;s/\n/&/2;Ta;/\n- id\: phase2$/s/.*\n//;P;D' test.yaml 

# Add updated timeout 
sed -i "/- id\: phase2/ i\\ 
    timeout: 900\\ 
" test.yaml 
+0

私はsedが単なる(代用)よりもはるかに多くを持っていることを知っていますが、私は決してそれを習得することができませんでした。しかし、awkの存在のために、私の動機はかなり低いです... – Scheff

+0

Lol、私はちょうど他のどこかから最初のsedをコピーしました。そのコマンドで実際に何が起こっていないか。 – Junaid

関連する問題