0.恭喜。您似乎发现了 gawk 中的一个错误。

0.恭喜。您似乎发现了 gawk 中的一个错误。

当 NF 与 FPAT 正则表达式一起使用时,逗号被视为字段。我更喜欢使用 NF 和 FPAT:

1) NF – 将输出限制为记录的实际字段数

2) FPAT – 处理引用字段中嵌入的逗号,如第 3 行:

 "Bus Driver, City/Transit",51

3) awk 脚本用于多个输入文件,这些文件的记录 6 的列数不同 - 记录 6 是文件内容的列名称/标题...

测试的输出,第一个 test1 使用固定值作为字段数,第二个 test2 使用 NF 作为字段数。

使用 gawk 4.1.4

    BEGIN {
            FPAT = "(^,)|([^,]+)|(\"[^\"]+\")"
            OFS = "\t"
        }

    NR == 6 {

       for (i = 1; 6 >= i; ++i) {
       #for (i = 1; NF >= i; ++i) {

           colName[i] = $i
           print "Column Name: " colName[i]

    }    

      { print "", "number of fields: " NF }
    }

输入文件从记录 6 开始:NR == 6 {...

    Occupation,States Licensed 
    Barber,51 
    "Bus Driver, City/Transit",51

我期望/想要的输出:

    Column Name: Occupation
    Column Name: States Licensed
        number of fields: 2

测试 1: for (i = 1; 6 >= i; ++i) {...

输出是正确的 - 我所期望/想要的,当然,除了无效但由于使用固定值 6 而显示的 4 列/字段。

    Column Name: Occupation
    Column Name: States Licensed
    Column Name: 
    Column Name: 
    Column Name: 
    Column Name: 
        number of fields: 2

测试 2: for (i = 1; NF >= i; ++i) {...

输出不是我期望/想要的;注意逗号是一个字段的指示

    Column Name: Occupation
    Column Name: ,
    Column Name: States Licensed
        number of fields: 3

答案1

0.恭喜。您似乎发现了 gawk 中的一个错误。

我已将其简化为一个非常小的示例。 (也许可以用更简单的FPAT字符串来演示该故障,但我不想再花十分钟。)基本上,对于像 之类的输入foo,bar,我们可以得到两个不同的结果。

案例一:

NF = 2
$1 = foo
$2 = bar
$3 =

情况B:

NF = 3
$1 = foo
$2 = ,
$3 = bar

这段代码产生情况B:

BEGIN {
        FPAT = "^,|[^,]+"
}

{
        print "NF =", NF
        print "$1 =", $1; print "$2 =", $2; print "$3 =", $3
}

(我从 中删除了括号FPAT,因为不需要它们;我删除了正则表达式中处理可能包含逗号的带引号字符串的部分,并将代码削减到最低限度。)

使用

回声 foo,酒吧 | awk-fawk_script 上方的名称

但是 - 至少在 gawk 版本 4.1.1 中 - 如果我在$1访问之前访问NF,那么我得到案例A。  您可以通过切换语句的顺序print或通过以下荒谬的组合来证明这一点:

{
        temp = $1                       # We will never use this.
        print "NF =", NF
        print "$1 =", $1; print "$2 =", $2; print "$3 =", $3
}

这显然是一个错误;不可能访问一个字段应该改变其他事物的值。 

1. 所以我们有一个解决方法。

temp = $1只需在循环之前添加for,我希望您会得到您想要的结果(使用 NF)。

2. 真正的(?)答案:

在上文中,我刻意避免将案例 A 或案例 B 称为“对”或“错”。情况 A 是您想要的情况,但情况 B 可能实际上是您想要的情况正确的FPAT结果为您正在使用的值 。这似乎是在说你想要一个字段

  • 以逗号开头的字符串,或
  • 一串由一个或多个非逗号字符组成的字符串,或者
  • 一个引号、一串由一个或多个非引号字符组成的字符串以及另一个引号。

但你不希望逗号成为一个字段;你只想要第二个和第三个选项。我发现那个设置

FPAT = "[^,]+|\"[^\"]+\""

会给你正确的结果。

相关内容