当 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 = "[^,]+|\"[^\"]+\""
会给你正确的结果。