在 awk 代码块或函数中可以使用 NF 做什么?

在 awk 代码块或函数中可以使用 NF 做什么?

参考:awk实用程序的 POSIX 标准

我真正怀念的一件事awk是能够使用分隔符连接数组,就像joinPerl 中的命令一样,通常是为了立即输出。

相反,我最终会编写如下代码

for (key in array)
    joined_string = (joined_string ==  "" ? array[key] : joined_string "," array[key])

print joined_string

或者

joined_string = array[1]
for (i = 2; i <= length(array); ++i)
    joined_string = joined_string "," array[i];

print joined_string

但是,awk如果我更改当前字段,可以为我执行此操作:

OFS="," # (would probably do this in BEGIN)

n = 0
for (key in array)
    $(++n) = array[key]

print

我相信这是完全合法的。但是,如果当前输入记录的字段多于数组array的条目数,这将在输出中产生垃圾(“垃圾”将是来自输入文件的数据)。因此,如果能够做到这一点就好了

OFS = "," # (would probably do this in BEGIN)

n = 0
for (key in array)
    $(++n) = array[key]

NF = n
print

我在标准中找不到任何说明NF允许修改的文本,但也没有任何文本说明不允许修改或调用未定义的行为。信息我发现是getline NF。这并不是说我不允许编写自己的函数或重置的代码块,而是在“函数”NF存在的情况下优先执行此操作。getline

还指出$0允许分配给并且这会重置NF。这是否意味着下面的代码会更好?

OFS = "," # (would probably do this in BEGIN)

$0 = ""
n = 0
for (key in array)
    $(++n) = array[key]

print

双重问题:

  1. 允许设置吗NF
  2. 最后一段代码是将数组与输出分隔符连接起来的正确方法吗?

答案1

据我所知没有标准记录设置副作用的文本NF,甚至是否允许设置。 Gawk 手册(也出版为有效的awk编程),这表示它尝试总体记录 Awk而不仅仅是 GNU 实现,包括以下内容:

递减NF会在新值NF和 重新计算后丢弃字段的值$0。 (直流)

带有警告

警告:某些版本的减少时awk不会重建。$0NF

“(dc)”提及意味着这是一个Awk 的“黑暗角落”,IE文档记录很少(或根本没有),并且不同实现的行为可能有所不同。

POSIX 将特殊变量定义为

由设置的变量awk

但它没有指定它们是否可以由程序设置(作为一般规则)。一些变量的规范确实提到它们可以被修改(参见ARGCARGV),其他变量的规范提到更改它们的后果是实现定义的(ENVIRON),其他变量仍然没有提及任何内容,但“显然”打算由程序(OFS等)。

在 的例子中NF,实验给出了部分答案:

  • 修改NFGNU Awk 中记录的工作,并且mawk行为方式相同;
  • 更改为NF真正的 awk被保留,但不会导致$0重新计算。

所以我想说

  1. 允许设置NF,但除了设置值之外可能不会有任何副作用。
  2. 自设定以来$0 由 POSIX 指定,根据规范,最后一个变体是正确的。 (是否是这样还有待商榷正确的方法,因为它输了$0。)

该函数在如何在 awk 中将数组转换为字符串?很有趣,但根据定义,它依赖于 GNU Awk 扩展,因此不是这个问题的答案。

(有些令人惊讶的是,其他可以设置的变量包括NRFNR,包括 TOTA 中的 。FILENAME但是,不能设置,或者更确切地说,设置它会清除其值。)

相关内容