繁体   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