4

私は 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]=%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

2 つの問題があります。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 に答える