我不知道这是AWK的功能或没有,但$0
和$1
不同的表现,如果我使用一个awk程序文件,并使用-f
VS如果我使用相同的命令上bash command line
。
获取以下测试文件:
a b c , e,f
a b c , e,f
a b c , e,f
a b c , e,f
a b c , e,f
a,bc, x
Run Code Online (Sandbox Code Playgroud)
当我在 bash 命令行上使用以下命令时:
awk "{ print $1 }" sample_input.txt
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
a b c , e,f
a b c , e,f
a b c , e,f
a b c , e,f
a b c , e,f
a,bc, x
Run Code Online (Sandbox Code Playgroud)
如您所见,这是 $0 而不是 $1 的输出。$0 只输出空行。
现在,当我在 awk 命令中使用相同的命令时,我得到了正确的输出:
{ print $1 }
awk -f test.awk sample_input.txt
a
a
a
a
a
a,bc,
Run Code Online (Sandbox Code Playgroud)
我正在使用 Ubuntu 18.04。这是一些奇怪的功能awk
吗?
这不是什么奇怪的特性,awk
而是由于 shell 处理双引号中变量的普通方式。
在命令中
awk "{ print $1 }" sample_input.txt
Run Code Online (Sandbox Code Playgroud)
由于awk
代码是双引号,shell 将替换$1
为第一个位置参数的值(通常是给脚本或 shell 函数的第一个命令行参数)。如果此值为空或未设置,则您的awk
脚本将变为
awk "{ print }" sample_input.txt
Run Code Online (Sandbox Code Playgroud)
具有相同的效果
cat sample_input.txt
Run Code Online (Sandbox Code Playgroud)
为了防止外壳扩展$1
,请单引号awk
脚本:
awk '{ print $1 }' sample_input.txt
Run Code Online (Sandbox Code Playgroud)
POSIX 标准描述了 shell 关于双引号和单引号的行为:
用单引号 (
''
)括起来的字符应保留单引号内每个字符的字面值。单引号内不能出现单引号。用双引号 (
""
)括起来的字符应保留双引号内所有字符的字面值,但反引号、<dollar-sign>
、 和字符除外<backslash>
,如下所示:
$
该
<dollar-sign>
应保留其特殊含义引入参数扩展(见参数扩展),命令替换的形式(见命令替换),和算术扩展(见算术展开)。[...]
( https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02_02 )