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
  • 333,661
yael
  • 13,106
  • 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нιη
  • 41,407
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
  • 153,898