以我的理解,$1
是第一个字段。但奇怪的是,awk '$1=$1'
省略了额外的空格。
$ echo "$string"
foo foo bar bar
$ echo "$string" | awk '$1=$1'
foo foo bar bar
为什么会发生这种情况?
答案1
当我们为字段变量赋值时,即。的值$1
被分配给 field $1
,awk 实际上$0
通过将它们与默认字段分隔符(或OFS
)空间连接来重建它。
我们也可以在以下场景中得到相同的情况......
echo -e "foo foo\tbar\t\tbar" | awk '$1=$1'
foo foo bar bar
echo -e "foo foo\tbar\t\tbar" | awk -v OFS=',' '$1=$1'
foo,foo,bar,bar
echo -e "foo foo\tbar\t\tbar" | awk '$3=1'
foo foo 1 bar
对于 GNU AWK,此行为记录在此处:
https://www.gnu.org/software/gawk/manual/html_node/Changing-Fields.html
$1 = $1 # 强制重建记录
答案2
echo "$string" | awk '$1=$1'
导致 AWK 评估$1=$1
,这会将字段分配给自身,并具有重新评估 的副作用$0
;然后 AWK 考虑表达式的值,并且因为它非零且非空,所以它执行默认操作,即 print $0
。
当 AWK 重新计算时,多余的空格将被删除$0
:它通过使用分隔符连接所有字段来实现这一点OFS
,默认情况下这是一个空格。当 AWK 解析记录时,$0
按原样包含整个记录,并$1
包含$NF
字段(不带分隔符);当任何字段被分配给时,$0
从字段值重建。
本例中 AWK 是否输出任何内容取决于输入:
echo "0 0" | awk '$1=$1'
不会输出任何东西。$1=$1
计算第一个字段中的任何内容,即0
本例中的内容;这是 AWK 中的“假”结果,因此什么也没有发生,也没有任何输出。为了避免这种情况,请转入$1=$1
一个操作并让 AWK 在所有情况下打印当前记录:
| awk '{$1=$1}1'
1
导致 AWK 始终运行默认操作。