对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
答案 0 :(得分: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 }
}
记住timeout:
行和空行的行号。因此,可以检查这些行是否恰好在注释模式(此处为- id: phase2
)匹配的行之前/前一行出现两行。
变量buf1
和buf2
用于进行某种循环缓冲(即每条线都回显第三行)。
因此,必须使用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
$
注意:
我没有检查边缘情况(例如,是否正确处理少于3行的文件)。
模式匹配和替换可能需要额外的逻辑。我确定提问者能够适当地调整脚本。
答案 1 :(得分: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