4

The following simple bash script prints the row number (from the file list.txt):

function get_row

{ 
  
[[ $1 = 1 ]] &&  awk '{print $1}' list.txt
[[ $1 = 2 ]] &&  awk '{print $2}' list.txt
 
} 


get_row 1
get_row 2

But I would like to write it more elegantly.

Is it possible to set $1 as variable as awk '{print $val}', so that if I call a function as get_row 1, the variable $val gets the value 1?

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
yael
  • 12,598
  • 51
  • 169
  • 303
  • 1
    This doesn't print rows. It will print the 1st or 2nd _column_ (field) of every line in the input file. Is that what you want? Or do you want the actual row (e.g. line 2) to be printed? – terdon Apr 24 '18 at 11:31

2 Answers2

8

Do you want something like this?

function get_column
{ 
    awk -v val=$1 '{print $val}' list.txt
}

Above is returning the column match with $1 passing to the function. if you really need print the line match with line number in $1 from function, instead use below.

function get_row
{ 
    awk -v val=$1 'NR==val{print ; exit}' list.txt
}

Or let shell evaluated and set the val value and print that within awk as following:

function get_column
{ 
    awk '{print $val}' val=$1 list.txt
}
function get_row
{ 
    awk 'NR==val{print ; exit}' val=$1 list.txt
}

Here you are passing val with only numbers and if val was contain backslash escape character you will encounter a problem which awk does C escape sequence processing on values passed via -v val= and a shell variable with val="\\n" will change to value with \n by awk.

αғsнιη
  • 40,939
  • 15
  • 71
  • 114
7

You can use:

field=$1 awk '{print $ENVIRON["field"]}'

it works in all POSIX compliant system, and you don't have to worry about code injection when using -v val=

Also the function should be named get_column instead of get_row.

cuonglm
  • 150,973
  • 38
  • 327
  • 406