4

我是 awk/gawk 的初学者。如果我在下面运行,shell 什么也没给我。请帮忙!

echo "A=1,B=2,3,C=,D=5,6,E=7,8,9"|awk 'BEGIN{
n = split($0, arr, /,(?=\\w+=)/)
for (x=1; x<n; x++) printf "arr[%d]=%s\n", x, arr[x]
}'

..................................................... ...

我正在尝试解析:

A=1,B=2,3,C=,D=5,6,E=7,8,9

预期输出:

A=1
B=2,3
C=
D=5,6
E=7,8,9

我敢打赌我的 awk 有问题。

4

7 回答 7

4

gawk支持前瞻。

如果您希望gawk按预期解析它,请尝试以下操作:

awk '{n=split(gensub(/,([A-Z])/, " \\1","g" ),arr," ");for(x=1;x<=n;x++)print arr[x]}'

用你的例子测试:

kent$  echo "A=1,B=2,3,C=,D=5,6,E=7,8,9"|awk '{n=split(gensub(/,([A-Z])/, " \\1","g" ),arr," ");for(x=1;x<=n;x++)print arr[x]}'
A=1
B=2,3
C=
D=5,6
E=7,8,9
于 2013-02-07T22:12:50.520 回答
3

使用 sed 可能会更容易:

$ echo "A=1,B=2,3,C=,D=5,6,E=7,8,9" | sed 's/,\(\w\+=\)/\n\1/g'
A=1
B=2,3
C=
D=5,6
E=7,8,9
于 2013-02-07T22:04:56.043 回答
2

如果你使用 gnu awk,你可以这样做:

awk '{printf $0 "\n" substr( RT, 2 )}' RS=,[A-Z]
于 2013-02-08T17:40:06.783 回答
1

作为 nhahtdh,在 awk 中没有前瞻...但是您可以为分配使用不同的分隔符。为什么不是“A=1;B=2,3,4;C=5...”?如果您的输入必须具有该格式,请尝试使用 flex...

于 2013-02-07T22:04:55.083 回答
1

您还可以使用逗号作为记录分隔符:

echo "A=1,B=2,3,C=,D=5,6,E=7,8,9" |
awk -v RS=, '{sep=","} /=/ {sep="\n"} NR==1 {sep=""} {printf "%s%s", sep, $0}'

输出

A=1
B=2,3
C=
D=5,6
E=7,8,9
于 2013-02-07T23:30:09.910 回答
0

你有两个问题。首先,你不想要一个BEGIN子句;您只希望它在每个输入行上运行。其次,您正在尝试使用 AWK 不支持的正则表达式功能。

与其尝试使用拆分字符串的花哨模式,不如使用循环和调用match()来解析出您想要的功能。

echo "A=1,B=2,3,C=,D=5,6,E=7,8,9"|awk '
{
    line = $0
    for (i = 0;;)
    {
        i = match(line, /([A-Z]+)=([0-9,]*)(,|$)/, arr)
        if (0 == i)
            break
        key = arr[1]
        value = arr[2]
        l = length(key "=" value ",") + 1
        line = substr(line, l)
        printf "DEBUG: key '%s' value '%s'\n", key, value
    }
}'

这打印:

DEBUG: key A value 1
DEBUG: key B value 2,3
DEBUG: key C value
DEBUG: key D value 5,6
DEBUG: key E value 7,8,9
于 2013-02-07T22:28:17.713 回答
0

使用 awk 的其他方式

awk '{print gensub(/,([A-Z]+=)/, "\n\\1","g")}' temp.txt

输出

A=1
B=2,3
C=
D=5,6
E=7,8,9
于 2013-02-08T03:04:59.603 回答