在AWK中使用字符串变量打印列

时间:2014-10-03 04:06:07

标签: awk gawk

我正在尝试在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列?

2 个答案:

答案 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结尾;如果你发现它存在,它只是清楚它包含的内容。