[英]bash - sed query to edit yaml file
我有一个 config.yaml 文件,其中包含以下我想使用 bash 脚本从配置中删除的 kafka 代理列表。
kafka.brokers:
- "node003"
- "node004"
我目前通过使用以下命令从脚本内部调用vi来执行此操作:
vi $CONF_BENCHMARK/config.yaml -c ":%s/kafka.brokers:\(\n\s*-\s".*"\)*/kafka.brokers:/g" -c ':wq!'
我知道sed是完成相同任务的更合适的工具,但是当我尝试将上述正则表达式转换为sed 时,它不起作用。
sed -i -e "s/kafka.brokers:\(\n\s*-\s".*"\)*/kafka.brokers:/g" $CONF_BENCHMARK/config.yaml
我做错了什么?
awk
来救援!
sed
是基于行的,这应该可以工作...
$ awk 's{if(/\s*-\s*"[^"]*"/) next; else s=0} /kafka.brokers:/{s=1}1' file
解释
if(/\\s*-\\s*"[^"]*"/) next
if 模式匹配跳到下一行
s{if(/\\s...
如果只设置了 s,则检查模式
/kafka.brokers:/{s=1}
看到 set s
1
打印行的简写(如果没有跳过)
s{... else s=0}
如果设置了 s 但找不到模式,则重置 s
正如其他人指出的那样,您需要明确地让 sed 使用乘法行。
真正的答案是使用AWK karakfa 提供了一个漂亮的答案。 但出于教育目的,我将提供一个 sed 答案:
sed '
/kafka.brokers/ {
:a
$be
N
/\n[[:space:]]*-[[:space:]]"[^\n]*"[^\n]*$/ba
s/\n.*\(\n\)/\1/
P;D
:e
s/\n.*//
}
' input
基本上 sed 会从kafka.brokers
到\\n[[:space:]]*-[[:space:]]"[^\\n]*"[^\\n]*$
不是火柴。
这将在模式空间中留下一个尾随行,即:
kafka.brokers:\n - "node003"\n - "node004"\nother stuff$
用换行符替换所有\\n.*\\(\\n\\)
留下以下模式空间:
kafka.brokers:\nother stuff$
P;D
将从模式空间打印第一行,然后用剩余的模式空间重新开始循环。 使输入支持:
kafka.brokers:
- "node003"
- "node004"
kafka.brokers:
- "node005"
more_input
您的 Vim 模式匹配多行,但 sed 逐行工作。 (也就是说,它首先尝试将您的模式与kafka.brokers:
匹配并失败,然后尝试匹配- "node003"
,等等。)您使用 Vim 以外的东西的直觉是正确的,但 sed 可能不是' t 在这里工作的最佳工具。
此答案更详细地解决了将多行模式与 sed 匹配的问题。
我个人的建议是使用像 Python 或 Perl 这样的脚本语言来处理复杂的模式匹配。 例如,您可以使用python -c <command>
运行 Python 命令,就像使用 Vim 一样,或者您可以编写一个从 Bash 脚本调用的小型 Python 脚本。 它比单行 sed 稍微复杂一些,但它可能会为您节省大量调试时间并使您的脚本更易于维护和修改。
考虑使用yq而不是sed
或awk
。 删除密钥kafka.brokers
就变得如此简单:
yq d $CONF_BENCHMARK/config.yaml '"kafka.brokers"'
以下代码段演示了yq
删除功能:
cat <<EOF | yq d - '"kafka.brokers"'
some:
path: value
kafka.brokers:
- "node003"
- "node004"
EOF
...并导致输出
some:
path: value
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.