shell AWK -重新编译记录仅为空格的$0会导致意外行为

dauxcl2d  于 2023-03-09  发布在  Shell
关注(0)|答案(2)|浏览(133)

AWK的默认"FS"变量是一个空格""删除记录中不必要的空格的常用技巧是使用以下命令强制重新编译记录:

{ $1 = $1 }

它确实修剪了空格。
然而,如果你有一行是由 * 整个 * 空白组成的,AWK会把它修剪成什么都没有(这很奇怪,因为你会期望留下一个""),出于某种原因,AWK现在会报告一个字段现在存在,而实际上那里什么都没有。

    • 输入文件:**
hello
    charles
           <--- This is a series of spaces
one
two
 three
    • AWK脚本:**
#!/usr/bin/awk -f

{ $1 = $1; print }
    • 输出:**
hello
charles

one
two
three

现在,这看起来是正确的,直到您让AWK使用"NF"变量报告它的字段计数:

    • 新的AWK脚本:**
#!/usr/bin/awk -f

{ $1 = $1; print NF }
    • 输出:**
1
1
1
1
1
1

这个字段到底是从哪里来的?当我通过cat实用程序运行输出来检查行尾时,它什么也没有报告:

dev@pop-os:~/Scripts/awk$ ./space_test.awk spaces.txt | cat -e
hello$
charles$
$
one$
two$
three$

如你所见,什么都没有。
更奇怪的是,AWK还报告这个记录的长度为零:

    • 修改的AWK脚本:**
#!/usr/bin/awk -f

{ $1 = $1; print length($0) }
    • 输出:**
5
7
0
3
3
5

这是怎么回事?

v6ylcynt

v6ylcynt1#

当你给一个字段赋值时,这个字段和它之前的所有字段都会被创建。如果它比原来的字段数多,那么NF就会增加。
字段是空的并不重要,它们仍然被计算在内。

$ awk '{print NF; $2 = ""; print NF}' <<< ""
0
2
06odsfpq

06odsfpq2#

AWK的默认"FS"变量是一个空格""
是的,但是这会提示GNU AWK将一个或多个空格字符作为字段分隔符,如果file.txt的字段由三个空格分隔,请考虑
那么

awk '{print NF,$3}' file.txt

给出输出

3 3
3 6
3 9

因此,$1=$1不仅会删除前导和尾随空白字符,而且会将所有空白字符更改为空格,然后将多个空格挤在一起,例如,如果您有TAB分隔文件file.tsv,如
那么

awk '{$1=$1;print}' file.tsv

给出输出
注意输出中没有TAB字符。

相关问题