这个让我很难过,而且我似乎找不到其他SO问题的精确匹配。我已经非常接近,所以也许有人可以指出我失踪的东西。
我有一个名为test.yml的yaml文件,如下所示:
sites:
qwerty:
hosts:
- qwerty.test
abc:
repo:
hosts:
- abc.test
other:
xyz:
repo:
hosts:
- xyz.test
utilities:
stuff:
- thing
- thing 2
我想使用bash脚本删除所有abc:block。我不能指望相同的行数。我愿意使用任何方法,只要它被广泛接受(这是一个开源项目)。理想情况下,完成后会看起来像这样:
sites:
qwerty:
hosts:
- qwerty.test
xyz:
repo:
hosts:
- xyz.test
utilities:
stuff:
- thing
- thing 2
现在我已经达到了这个目标:
sed -e "/ abc:/,/ \w/d" test.yml > test.tmp
但结果是:
sites:
qwerty:
hosts:
- qwerty.test
我的思维过程是匹配,直到有两个空格和一个单词但我似乎匹配两个空格,当有四个并删除所有内容。如何使用Regex明确地定位两个空格和一个单词?或者有更好的方法吗?
答案 0 :(得分:1)
要操作json
和yaml
文件,您应该使用原生数据格式的工具。
您可以使用[ y2j ]中指出的comment。从git repo下载zip并将其解压缩到文件夹。将您的yaml文件放在前面提到的文件夹中,然后执行:
# cat test.yaml
sites:
qwerty:
hosts:
- qwerty.test
abc:
repo:
hosts:
- abc.test
other:
xyz:
repo:
hosts:
- xyz.test
utilities:
stuff:
- thing
- thing 2
# ./y2j 'del(.[].abc)' <test.yaml | ./j2y
sites:
qwerty:
hosts:
- qwerty.test
xyz:
hosts:
- xyz.test
repo: null
utilities:
stuff:
- thing
- thing 2
答案 1 :(得分:1)
这将根据您的输入数据工作。
awk 'BEGIN{ print_flag=1 }
{
if( $0 ~ / abc:/ )
{
print_flag=0;
next
}
if( $0 ~ /^ [a-zA-Z0-9]+:$/ )
{
print_flag=1;
}
if ( print_flag == 1 )
print $0
} ' input.txt
sites:
qwerty:
hosts:
- qwerty.test
xyz:
repo:
hosts:
- xyz.test
utilities:
stuff:
- thing
- thing 2
问候!
答案 2 :(得分:0)
一个简单但不是特别灵活的awk解决方案可能是这样的:
awk -v tag="abc:" '/^ [^ ]/ {n=0} /^ [^ ]/ && $1==tag {n=1} (1-n)' input.yaml
为便于阅读而破裂:
-v tag="abc:"
- 设置一个将从您的输入中删除的变量。/^ [^ ]/ {n=0}
- 如果我们发现自己在一条用两个空格缩进的线上,则开始打印。/^ [^ ]/ && $1==tag {n=1}
- 但如果该行的第一个字是我们上面指定的标记,停止打印。(n-1)
- 如果n = 0,则打印该行。您可以选择颠倒n
的含义,如下所示:
awk -v n=1 -v tag="abc:" '/^ [^ ]/{n=1} /^ [^ ]/ && $1==tag {n=0} n' input.yaml
请注意,使用此用法时,我们需要“填充”n
变量,以便打印/^ [^ ]/
的第一个实例之前的行。
这不是一个yaml解析器,它是一个文本模式解析器。您可以轻松地为其提供格式不同的完全有效的yaml,因此会被错误地解析。
理论上我可以在awk中对非常有限的实际yaml进行解析。你会遗漏很多数据类型,但你可以写一些比上面的解决方案更灵活的东西。但是,管理一组复杂的awk函数似乎比向工具箱中添加jq
和y2j
等工具要多得多。如果你在yaml中操作文件,我会提交你想要yaml的原生支持,而不是像这样的黑客。
答案 3 :(得分:0)
这可能适合你(GNU sed):
abc
如果它不以abc
开头,我们不感兴趣。如果是,并且它是最后一行,请将其删除。否则,追加下一行并检查缩进是否相同。如果不是,则追加另一行并再次检查(如果在任何时候它是最后一行,则删除到目前为止收集的所有行)。如果附加的行与第一行(即从{{1}}开始的行缩进,则删除除最后一行之外的所有行,然后从第一个命令重复。