为什么这个awk脚本没有按预期运行?

时间:2011-06-29 16:01:38

标签: awk gawk

我有以下测试脚本

 /^[^a-zA-Z0-9]/  {
    DATEd[$3] = $1
    } 
   END { 
        print "        \"data\": ["
        for (i = 0 ; i <= 5; i ++ ) {
            { print "            [" i ", \"" DATEd[i] "\"],"}
        }
        print "        ]"
}

正在阅读此文本文件

2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399
2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399 
2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399 
2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399
2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399 
2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399

但它没有打印出我想要的东西,我希望它打印出来

    "data": [
        [0, "2011-01-22"],
        [1, "2011-01-22"],
        [2, "2011-01-22"],
        [3, "2011-01-22"],
        [4, "2011-01-22"],
        [5, "2011-01-22"],
    ]

当它实际上只是打印出来时

"data": [
    [0, ""],
    [1, ""],
    [2, ""],
    [3, ""],
    [4, ""],
    [5, ""],
]

那么为什么“DATEd [$ 3] = $ 1”为空?

另外,我如何检查阵列的长度? 在这种情况下,DATEd.length不起作用。

由于

EDIT_ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ ___

所以在@Fredrik和@geekosaur的帮助下,我已经到了这里,现在到了最后一些问题

1)脚本现在看起来像这样

 /[a-zA-Z0-9]/  {
    DATEd[NR-1] = $1
    } 
   END { 
        print "        \"data\": ["

        for (i in DATEd) {
            { print "            [" i ", \"" DATEd[i] "\"],"}
        }
        print "        ]"
}

并提供以下输出

"data": [
    [4, "2011-01-26"],
    [5, "2011-01-27"],
    [6, "2011-01-28"],
    [0, "2011-01-22"],
    [1, "2011-01-23"],
    [2, "2011-01-24"],
    [3, "2011-01-25"],
]

但我希望它看起来像这样

"data": [
[0, "2011-01-22"],
[1, "2011-01-23"],
[2, "2011-01-24"],
[3, "2011-01-25"],
[4, "2011-01-26"],
[5, "2011-01-27"],
[6, "2011-01-28"]
]

I.E排序并删除最后结束']'字符前的最后一个','字符。这有可能以一种简单的方式得到解决吗? =)

谢谢=)

编辑3最终结果_ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ ____

使用了@geekosaur和@Fredrik贡献的组合=)

{
    DATEd[NR-1] = $1; len++
}
   END { 
        print "        \"data\": ["

        #for (i in DATEd) {
        for (i = 0 ; i <= len-1; i ++ ) {
            { print "            [" i ", \"" DATEd[i] "\"],"}
        }
        print "        ]"
}

2 个答案:

答案 0 :(得分:0)

首先,你的正则表达式是错误的,/^[^a-zA-Z0-9]/表示匹配行的开头而不是字母或数字。没有任何行具有该设置,因此,您的数组DATe为空。

其次,你的数组没有被0-5索引,而是3美元的内容(如果你修复你的正则表达式)

没有内置函数来获取数组的长度,但实现数组很简单。

数组示例

function array_length(a) {
    for (i in a) n++
    return n
}

{
    DATEd[NR] = $1
}
END {
    for (i in DATEd) {
        print i, DATEd[i]
    }
    print "Number of items", array_length(DATEd)

    # copy indices
    j = 1
    for (i in DATEd) {
        ind[j] = i    # index value becomes element value
        j++
    }
    n = asort(ind)    # index values are now sorted
    for (i = 1; i <= n; i++)
        print i, DATEd[ind[i]]
}

给出:

4 2011-01-22
5 2011-01-22
6 2011-01-22
1 2011-01-22
2 2011-01-22
3 2011-01-22
Number of items 6
1 2011-01-22
2 2011-01-22
3 2011-01-22
4 2011-01-22
5 2011-01-22
6 2011-01-22

有关数组的说明,请参阅gnu awk manual

要循环遍历数组的所有元素,请使用此构造(请参阅上面的链接)

 for (var in array)
   body

答案 1 :(得分:0)

如果没有-F选项,$3将为P16A22_110114072915(或者如果您的选择器正则表达式是正确的话)。你真正想要的是什么价值?你想要NR吗?

awk不是面向对象的;它的阵列支持是善良的,缺乏。您需要自己跟踪阵列的长度。 (只是为了让您了解awk数组支持的限制:您无法分配数组。您必须分配单个索引或使用split()。)