如何跟踪for循环中的打印项目?

时间:2015-06-24 15:38:45

标签: arrays for-loop awk

我是recently处理我希望以一种很好的方式打印的哈希。

为简化起见,它只是一个包含两个字段a['name']="me"a['age']=77的数组,以及我想要打印的数据key1:value1,key2:value2,...,并以新行结束。那就是:

name=me,age=77

由于它不是一个索引是自动增量值的数组,我不知道如何遍历它们并知道我何时处理最后一个。

这很重要,因为它允许在我最后一个案例中使用不同的分隔符。像这样,在这种情况下可以打印不同的字符(换行),而不是在其余文件(逗号)之后打印的字符。

我最终使用计数器来比较数组的长度:

awk 'BEGIN {a["name"]="me"; a["age"]=77;
            n = length(a);
            for (i in a) {
                count++; 
                printf "%s=%s%s", i, a[i], (count<n?",":ORS)
                }
            }'

这很有效。但是,有没有其他更好的方法来处理这个?我不喜欢添加额外的count++

1 个答案:

答案 0 :(得分:2)

通常,当你知道循环的终点时,你会在每个字段后放置OFS或ORS:

for (i=1; i<=n; i++) {
    printf "%s%s", $i, (i<n?OFS:ORS)
}

但是如果你不这样做,那么你将OFS放在第二个和后续的字段之前并在循环之后打印ORS:

for (idx in array) {
    printf "%s%s", (++i>1?OFS:""), array[idx]
}
print ""

我喜欢:

n = length(array)
for (idx in array) {
    printf "%s%s", array[idx], (++i<n?OFS:ORS)
}

想要获得循环的结束,但length(array)是特定于gawk的,并且结果代码不比上面的第二个循环更简洁或更有效:

$ cat tst.awk
BEGIN {
    OFS = ","
    array["name"] = "me"
    array["age"]  = 77 
    for (idx in array) {
        printf "%s%s=%s", (++i>1?OFS:""), array[idx], idx
    }
    print ""
}

VS

$ cat tst.awk
BEGIN {
    OFS = ","
    array["name"] = "me"
    array["age"]  = 77 
    n = length(array)      # or non-gawk: for (idx in array) n++
    for (idx in array) {
        printf "%s=%s%s", array[idx], idx, (++i<n?OFS:ORS)
    }
}