2014-10-03 68 views
1

我想在我的AWK(或GAWK)程序中使用一个变量来打印多个列。在AWK中使用字符串变量打印列

这是我在列命令行打印:

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列?

+1

如果你在BEGIN块中这样做,它将不起作用。 – 2014-10-03 04:26:35

回答

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 

更新

要么你必须生成脚本像乔纳森·莱弗勒因为如何表现不同的是壳(和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 
+0

我实际上会从数组中获取要打印的列,并且希望定义要打印一次的值,而不是连续循环包含要打印的列数的数组。我只是试图保持简单的例子。 – DJElbow 2014-10-03 04:46:03

+0

更新示例 – DJElbow 2014-10-03 05:41:56

+0

感谢您的示例。我可能会最终使用类似的解决方案。 – DJElbow 2014-10-03 16:07:22

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 

要打印的列被示出为在这里字符串,一个击功能,但可能来自一个文件,或其它来源如需要。 trap命令是确保临时文件script.awk被删除的shell脚本。如果脚本同时运行,将进程ID嵌入名称中可能会更好,以确保唯一性。如果你真的担心它,请使用mktemp或类似的程序来创建一个更难猜的名字。不要求脚本文件以.awk结尾;它只是说明它包含了什么,如果你发现它躺在周围。