Regex with awk or gawk



我是awk/gawk的初学者。如果我跑到下面,炮弹什么也不会给我。请帮忙!

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]=%sn", 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

我打赌我的锥子肯定有毛病。

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

使用sed:可能会更容易

$ echo "A=1,B=2,3,C=,D=5,6,E=7,8,9" | sed 's/,(w+=)/n1/g'
A=1
B=2,3
C=
D=5,6
E=7,8,9

如果您使用的是gnu-awk,您可以执行以下操作:

awk '{printf $0 "n" substr( RT, 2 )}' RS=,[A-Z]

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

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

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

您有两个问题。首先,您不需要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

使用awk 的其他方式

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

输出

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

最新更新