【发布时间】:2016-11-30 05:49:30
【问题描述】:
A=(aaa bbb ccc)
cat abc.txt | awk '{ print $1, ${A[$1]} }'
我想根据 $1 索引一个数组元素,但上面的代码在 awk 语法中不正确。有人可以帮忙吗?
【问题讨论】:
A=(aaa bbb ccc)
cat abc.txt | awk '{ print $1, ${A[$1]} }'
我想根据 $1 索引一个数组元素,但上面的代码在 awk 语法中不正确。有人可以帮忙吗?
【问题讨论】:
您不能使用在awk 中生成的值来索引bash 数组,即使您没有使用单引号(从而防止bash 进行任何替换)。不过,您可以将数组传入。
A=(aaa bbb ccc)
awk -v a="${A[*]}" 'BEGIN {split(a, A, / /)}
{print $1, A[$1] }' <abc.txt
由于 awk 内部的 split 功能,A 的元素不能包含空格或换行符。如果您需要做一些更有趣的事情,请将数组设置在 awk 内。
awk 'BEGIN {a[1] = "foo bar" # sadly, there is no way to set an array all
a[2] = "baz" } # at once without abusing split() as above
{print $1, a[$1] }' <abc.txt
(澄清:bash 替换变量 之前 调用您要替换的参数的程序,所以当您在 awk 中找到 $1 时,问 @987654331 为时已晚@ 使用它来替换 A 的特定元素。)
【讨论】:
cat 的无用使用”。
awk 接受一个输入文件。 awk '{}' filename
< 重定向它,正如 kurumi 指出的那样。而awk '{...}' A=foo filename will work, the form that you have, awk A=foo '{...}' filename` 不会。但是,您可以使用awk -v "A=foo" '{...}' filename。
如果您要对 A 数组进行硬编码,您可以在 awk 中初始化它
awk 'BEGIN{A[0]="aaa";A[1]="bbb"}{ print $1, A[$1] }' abc.txt
【讨论】:
单引号内的 awk 程序看不到 shell 环境变量 A。通常,如果使用双引号而不是单引号,则可以进行一些 shell 替换,但这是由 shell 在 awk 之前完成的调用。总的来说,尝试以这种方式将 shell 和 awk 结合起来是很费劲的。如果可能的话,我会采用 kurumi 使用 awk 数组的方法。
单引号:不可穿透的面纱。 双引号:一般来说太辛苦了。 所以选择你的毒药:shell 或 awk。 否则:您的代码可能会失败。
【讨论】:
您还可以使用 printf 在单独的行上打印数组的每个元素并将其通过管道传输到 awk。此代码将简单地从 awk 打印 bash 数组 (bash_arr):
bash_arr=( 1 2 3 4 5 )
printf '%s\n' "${bash_arr[@]}" |
awk ' { awk_arr[NR] = $0 }
END {
for (key in awk_arr) {
print awk_arr[key]
}
}'
【讨论】: