我正在尝试在AWK(或GAWK)程序中使用一个变量来打印多个列。
我正在从命令行打印列:
gawk -v cols=1,2,3 -f sample.awk -F,
我希望能够在BEGIN{}
块中设置此变量,并在程序的主要部分中使用它。
BEGIN{
split(cols, col_arr, FS)
i=1;
col_str = "$"col_arr[1];
for(col in col_arr){
if (i > 1){
col_str = col_str",$"col;
}
i++;
}
}
{
print col_str
}
然而,这只会打印" $ 1,$ 2,$ 3"。如何更改此项以打印第1,2和3列?
答案 0 :(得分:1)
A BEGIN rule is executed once only, before the first input record is read.
尝试这样的事情
awk '{cols = $1 OFS $2 OFS $5; print cols}' file
<强> 更新 强>
你必须生成像Jonathan Leffler所展示的脚本,因为不像shell(和PERL),AWK不会评估字符串中的变量,或类似的东西
BEGIN{
sub(/,$/,"",cols)
n=split(cols,C,/,/)
}
function _get_cols(i,s){
for(i=1;i<=n;i++) s = length(s) ? s OFS $(C[i]) : $(C[i])
return s
}
{
print _get_cols()
}
执行
awk -v cols=2,3, -f test.awk infile
或者其他类似的东西你必须尝试
#!/bin/bash
# Usage : _parse <FS> <OFS> 1 2 3 ... n < file
_parse()
{
local fs="$1"
local ofs="$2"
shift 2
local _s=
local f
for f; do
_s="${_s}\$${f},"
done
awk -F"$fs" -v OFS="$ofs" "{ print ${_s%,} }"
}
# Call function
_parse ' ' '\t' 1 3 < infile
答案 1 :(得分:1)
最好使用程序(可能是awk
)来编写最终运行的awk
脚本。
例如:
trap "rm -f script.awk; exit 1" 0 1 2 3 13 15
awk '{ printf "{ print ";
pad = ""; for (i = 1; i <= NF; i++) { printf "%s$%d", pad, $i; pad = ", " }
print " }"
}' <<< "1 2 5" > script.awk
awk -f script.awk data.file
rm -f script.awk
trap 0
要打印的列显示为此处字符串,Bash功能,但可以来自文件,也可以来自其他来源。 trap
命令是shell脚本,用于确保删除临时文件script.awk
。如果脚本同时运行,最好在名称中嵌入进程ID以确保唯一性。如果您真的担心它,请使用mktemp
或类似的程序来创建更难猜的名称。不要求脚本文件以.awk
结尾;如果你发现它存在,它只是清楚它包含的内容。