簡體   English   中英

使用sed刪除特定模式之前的兩行

[英]Delete two lines before a specific pattern using sed

對sed不太熟悉,我試圖刪除模式前的2行(超時值和空行),然后用更新的超時重新插入兩行。

這是我所擁有的yaml文件的一部分:

- id: phase1
  blahblahbal
  timeout: 720

- id: phase2
  blahblahbalh
  timeout: 1800

我正在嘗試將第一次超時更新為“ 900”。

這是我對grep的看法:

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

然后使用sed插入更新值。 這是可行的,但grep看起來不太好。 有沒有一種方法可以刪除模式前帶有sed的兩行?

第一次sed / grep后的預期輸出:

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

最終預期輸出:

- id: phase1
  blahblahbal
  timeout: 900

- id: phase2
  blahblahbalh
  timeout: 1800

這是可以使用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 }
}

會記住timeout:的行號timeout: line和空白行。 因此,可以檢查這些行是否與所標記的模式(此處為- id: phase2 )匹配的行恰好出現在前兩行/前一行。

變量buf1buf2用於進行某種循環緩沖(即,每行最后一行的第三行回顯)。

因此, 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. 我沒有檢查邊緣情況(例如,少於3行的文件是否正確處理)。

  2. 模式匹配和替換可能需要其他邏輯。 我確定發問者將能夠適當地調整腳本。

這是我用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM