如何根据条件从数据块中获取特定数据

Jot*_*tne 6 bash awk sed

我有这样一个文件:

[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)

这有几个错误:

  1. 我不能够设置RS[group],无论是失败RS="[group]"RS="\[group\]".如果name或其他标签包含,则会失败group.
  2. 我不想使用RS多个字符,因为这gnu awk只是.

有人有其他建议吗?sed或者awk不使用长链命令.

Jen*_*rat 6

如果您知道组始终用空行分隔,请设置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)


dev*_*ull 5

你的问题似乎是:

我无法设置RS来[group],无论失败RS="[group]"RS="\[group\]".

他说:

RS="[[]group[]]"
Run Code Online (Sandbox Code Playgroud)

应该产生预期的结果.


Ed *_*ton 5

在这些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 mapsplit("",map).

与使用RE和/或sub()等等相比,它使得解决方案更加健壮和可扩展,以防您希望将来比较和/或打印其他字段的值.