PROCINFO 如何在特定记录上显示有关 FS 的信息?

时间:2021-01-10 21:21:01

标签: awk gnu

我正在阅读 GNU Awk User's Guide → 7.5.2 Built-in Variables That Convey Information 上的 PROCINFO 内置变量的定义:

<块引用>

PROCINFO #

此数组的元素提供对有关正在运行的 awk 程序的信息的访问。以下元素(按字母顺序排列)保证可用:

PROCINFO["FS"]

如果使用 "FS" 进行字段拆分有效,则为 FS,如果使用 "FIELDWIDTHS" 进行字段拆分有效,则为 FIELDWIDTHS,如果与"FPAT" 有效,如果字段拆分由 API 输入解析器控制,则为 FPAT

是的,它工作得很好。当我提供字符串 "hello;you" 并按顺序将 "API" 设置为 ";"、FS 为 "2 2 " 和 FIELDWIDTHS 为三个字符时,请参阅此示例:

FPAT

这很好,效果很好。

他们在4.8 Checking How gawk Is Splitting Records中提到之前的那个:

<块引用>

要判断哪种字段拆分有效,请使用 $ gawk 'BEGIN{FS=";"}{print PROCINFO["FS"]; print $1}' <<< "hello;you" FS hello $ gawk 'BEGIN{FIELDWIDTHS="2 2 2"}{print PROCINFO["FS"]; print $1}' <<< "hello;you" FIELDWIDTHS he $ gawk 'BEGIN{FPAT="..."}{print PROCINFO["FS"]; print $1}' <<< "hello;you" FPAT hel (参见 Built-in Variables That Convey Information 部分)。如果使用常规字段拆分,则值为 PROCINFO["FS"],如果使用固定宽度字段拆分,则值为 "FS",如果使用基于内容的字段拆分,则值为 "FIELDWIDTHS"

同样在 Changing FS Does Not Affect the Fields 中,它们描述了更改如何影响下一条记录

<块引用>

根据 POSIX 标准,awk 的行为应该就像每条记录在读取时被拆分为字段一样。特别是,这意味着如果您在读取记录后更改 "FPAT" 的值,字段的值(即它们如何拆分)应反映 FS 的旧值,而不是新的。

这个案例很好地解释了:

FS

考虑到所有这些,我认为 $ gawk 'BEGIN{FS=";"} {FS="|"; print $1}' <<< "hello;you bye|everyone" hello # "hello;you" is splitted using FS=";", the assignment FS="|" doesn't affect it yet bye # "bye|everyone" is splitted using FS="|" 将始终将 PROCINFO["FS"] 反映为正在打印的记录中的字段拆分。
但是,请参阅此案例:

"FS"

$ gawk 'BEGIN{FPAT="..."}{FS=";"; print PROCINFO["FS"]; print $1}' <<< "hello;you" FS hel 显示当前记录 (FS) 中设置的信息,而不是 Awk 在处理数据时考虑的信息(即 FPAT)。如果我们交换分配,也会发生同样的情况:

PROCINFO["FS"]

为什么 $ gawk 'BEGIN{FS=";"}{FPAT="..."; print PROCINFO["FS"]; print $1}' <<< "hello;you" FPAT hello 显示的 FS 与打印它的记录中使用的 FS 不同?

1 个答案:

答案 0 :(得分:2)

字段拆分(使用 FS、FIELDWIDTHS 或 FPAT)在读取记录或为整个 $0 赋予新值时发生,否则(例如 $0="foo"sub(/foo/,"bar"))。 print PROCINFO["FS"] 告诉您 PROCINFO["FS"] 当前具有的值,该值不一定与上次发生字段拆分时的值相同。

与:

$ gawk 'BEGIN{FPAT="..."}{FS=";"; print PROCINFO["FS"]; print $1}' <<< "hello;you"
FS
hel

您正在设置 FS=";" $1 已经基于 FPAT="..." 填充,然后打印 PROCINFO["FS"] 新值(这将是使用下次将记录拆分为多个字段),然后打印在设置 $1 之前填充的 FS=";" 值。

如果您将 $0 设置为自身,字段拆分将再次发生,这次使用新的 FS 值而不是原始 FPAT 值:

$ gawk 'BEGIN{FPAT="..."}{FS=";"; print PROCINFO["FS"]; print $1; $0=$0; print $1}' <<< "hello;you"
FS
hel
hello