Search code examples
awkgawk

Print columns using string variable in AWK


I am trying to use one variable in my AWK (or GAWK) program to print multiple columns.

I am taking the columns to print from the command line:

gawk -v cols=1,2,3 -f sample.awk -F,

I want to be able to set this variable in my BEGIN{} block, and use it in the main part of my program.

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
}

However, this will just print "$1,$2,$3". How can I change this to print columns 1, 2, and 3?


Solution

  • A BEGIN rule is executed once only, before the first input record is read.

    Try something like this

    awk '{cols = $1 OFS $2 OFS $5; print cols}' file
    

    Update

    Either you have to generate script like how Jonathan Leffler showed since unlike the shell (and PERL) AWK does not evaluate variables within strings, or something like this

    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()
    }
    

    Execute

    awk -v cols=2,3, -f test.awk infile
    

    OR Else something like this you have to try

    #!/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