在 shell 脚本中使用 awk 和变量

在 shell 脚本中使用 awk 和变量

我有一个名为“随机”的文件,如下所示:

A B C D
A B C D
A B C D

我怎样才能让这个 shell 脚本打印出第二列?

#! /usr/bin/tcsh -f

set variable = "2"
awk '{print "$""'"$variable"'" }' random

它给:

$2
$2
$2
$2
$2

如果我像这样硬编码 $2:

#! /usr/bin/tcsh -f

awk '{print $2 }' random

我明白了

B
B
B

但我需要每次都设置不同的值,因此硬编码不是一个选项

答案1

使用 awk 的选项将变量传递给 awk -v。例如将 awk 变量设置n为与 csh 变量相同的值$variable

% set variable=2
% awk -v n="$variable" '{print $n}' random
B
B
B

或者,在脚本之后将变量赋值作为参数传递(awk 会将参数解释x=y为赋值,而不是文件名):

% set variable=4
% awk '{print $n}' n="$variable" random
D
D
D

在这两种情况下,awk 脚本都会解释$n为“编号为 n 的字段”

或者,您可以使用环境变量。 awk 可以通过数组访问它们ENVIRON。例如

% setenv variable 2
% awk '{print $ENVIRON["variable"]}' random
B
B
B

顺便说一句,正如其他人在评论中提到的那样,csh/tcsh对于脚本语言来说不是一个好的选择 - 使用类似 bourne 的 shell 来编写 shell 脚本。 tcsh对于交互式 shell 来说仍然还算不错,但不提供其他 shell 尚未提供的任何内容 - csh 在 20 世纪 80 年代是一个优秀的交互式 shell,但其他 shell 早已超越了它(并且 csh 具有缺点与良好的脚本 shell 语言不同,因此您不会仅通过交互使用它来获得脚本编写经验)。尝试切换到 bash、ksh 或 zsh。

答案2

我并不记得 (t)csh 的所有怪癖,但我认为这与它在类似 POSIX 的 shell 中的工作方式类似。您有一个带引号的 string '{print "$""',包括双引号;然后是引用的变量扩展"$variable";然后是另一个带引号的字符串'" }'。 awk 得到的是{print "$""2" },有两个背靠背的 awk 字符串,它们是 awk 连接起来的。但它们是字符串,而不是$运算符。

awk '{print "$""'"$variable"'" }'
    <--quoted---><---var---><-q-> 

去掉多余的双引号:

tcsh> set variable = 2
tcsh> echo a b c | awk '{print $'"$variable"' }'
b

或者在 POSIX-y shell 中:

$ variable=2
$ echo a b c | awk '{print $'"$variable"' }'
b

相关内容