我开始学习awk
并遇到一些事情,当我运行以下命令时
$ echo ":a:b:c:" | awk '$1=$1' FS=":" OFS="$"
$ echo "a:b:c:" | awk '$1=$1' FS=":" OFS="$"
a$b$c$
第一个命令不返回任何内容,但我希望它返回$a$b$c$
,与第二个命令类似。一般来说,当字段分隔符位于行开头时,它不会打印任何内容。为什么这样?
答案1
在您的脚本中,打印作为默认操作被触发,这又取决于作为模式的awk
分配的“副作用”评估。$1=$1
在第一种情况下,第一个分隔符之前有一个空字段,$1
空字符串也是如此,其计算结果为 FALSE。在第二种情况下,$1
是非空字符串a
,其计算结果为 TRUE,触发默认打印操作。
答案2
您依靠第一个字段的真值来使 awk 打印记录。空字符串的真值为假,因此 awk 除了赋值之外不执行任何操作。显式打印(或使用其他始终为真的条件,例如1
),而不是使用第一个字段作为检查:
echo ":a:b:c:" | awk '{$1=$1; print}' FS=":" OFS="$"
答案3
- 不要让操作的结果评估为条件,除非您有非常具体的需求(例如,您尝试删除存在的字符,并希望在成功时执行某些操作)。
- 当您在看到使用变量的代码之前看到变量被设置时,代码更具可读性,因此不要在文件列表中列出变量分配后除非您有非常具体的需要(例如更改文件之间的值),否则请在调用 awk 之前 使用
-v
或或一个赋值将它们列出来,您可以从中访问(请参阅BEGIN
ENVIRON[]
https://stackoverflow.com/q/19075671/1745001)。 - 在 shell 中使用单引号括住所有字符串(包括脚本),除非您有非常具体的需要使用双引号或不使用引号(请参阅https://mywiki.wooledge.org/Quotes)。
所以你的脚本应该是awk -F':' -v OFS='$' '{$1=$1}1'
.