我有这样一个文件:
[group]
enable = 0
name = green
test = more
[group]
name = blue
test = home
[group]
value = 48
name = orange
test = out
Run Code Online (Sandbox Code Playgroud)
标签=
和值之间可能有一个或多个空格/标签.
每个块中的行数可能会谨慎.
我喜欢拥有name
,只有这不是真的enable = 0
所以输出应该是:
blue
orange
Run Code Online (Sandbox Code Playgroud)
这是我设法创建的:
awk -v RS="group" '!/enable = 0/ {sub(/.*name[[:blank:]]+=[[:blank:]]+/,x);print $1}'
blue
orange
Run Code Online (Sandbox Code Playgroud)
这有几个错误:
RS
到[group]
,无论是失败RS="[group]"
和RS="\[group\]"
.如果name
或其他标签包含,则会失败group
.RS
多个字符,因为这gnu awk
只是.有人有其他建议吗?sed
或者awk
不使用长链命令.
如果您知道组始终用空行分隔,请设置RS
为空字符串:
$ awk -v RS="" '!/enable = 0/ {sub(/.*name[[:blank:]]+=[[:blank:]]+/,x);print $1}'
blue
orange
Run Code Online (Sandbox Code Playgroud)
@devnull在他的回答中解释说GNU awk也接受正则表达式RS
,所以你只能[group]
在它自己的行上拆分:
gawk -v RS='(^|\n)[[]group]($|\n)' '!/enable = 0/ {sub(/.*name[[:blank:]]+=[[:blank:]]+/,x);print $1}'
Run Code Online (Sandbox Code Playgroud)
这确保我们不会像邪恶的名字一样分裂
[group]
enable = 0
name = [group]
name = evil
test = more
Run Code Online (Sandbox Code Playgroud)
你的问题似乎是:
我无法设置RS来
[group]
,无论失败RS="[group]"
和RS="\[group\]"
.
他说:
RS="[[]group[]]"
Run Code Online (Sandbox Code Playgroud)
应该产生预期的结果.
在这些name = value
记录中有明确语句的情况下,我喜欢先用这些映射填充数组,例如:
map["<name>"] = <value>
Run Code Online (Sandbox Code Playgroud)
然后只使用名称来引用我想要的值.在这种情况下:
$ awk -v RS= -F'\n' '
{
delete map
for (i=1;i<=NF;i++) {
split($i,tmp,/ *= */)
map[tmp[1]] = tmp[2]
}
}
map["enable"] !~ /^0$/ {
print map["name"]
}
' file
blue
orange
Run Code Online (Sandbox Code Playgroud)
如果您的awk版本不支持删除整个数组,请更改delete map
为split("",map)
.
与使用RE和/或sub()等等相比,它使得解决方案更加健壮和可扩展,以防您希望将来比较和/或打印其他字段的值.