Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing bash array elements to awk regex inside loop

Tags:

regex

bash

awk

I'm trying to search through a file using awk, by looping over elements of a bash array. This is what I'm currently doing

myarray[1] = 441
myarray[2] = 123

for i in "${myarray[@]}"
do
awk '{if ($4 == '"$i"') print $0}' myfile.txt > newfile.txt
done

Is it possible to access elements of a bash array in awk in this way?

like image 229
tclarke Avatar asked Aug 22 '14 13:08

tclarke


3 Answers

This is not the right way to pass a shell variable (or BASH array element) to awk. Use it with -v option:

myarray=(441 123)

for i in "${myarray[@]}'"; do
   awk -v i="$i" '$4 == i' myfile.txt > newfile.txt
done
  • -v i="$i" makes shell variable $i available inside awk as an awk variable i
  • $4 == i is equivalent of {if ($4 == i) print $0} since print $0 is the default action
like image 52
anubhava Avatar answered Oct 18 '22 03:10

anubhava


There's no need for a bash loop; you can do the whole thing in awk:

my_array=(441 123)
awk -varr="${my_array[*]}" 'BEGIN{split(arr,a); for(i in a)b[a[i]]} $4 in b' file

The contents of the shell array are passed to awk as a single string, with a space in between each element. split is used to create an awk array from the string. Array a looks like this:

a[1]=441; a[2]=123

The for loop creates an array b with two keys, b[441] and b[123].

Lines are printed when the 4th column matches one of the array keys.

Bear in mind that this approach fails when the elements in the array contain spaces.

like image 26
Tom Fenech Avatar answered Oct 18 '22 04:10

Tom Fenech


You can avoid looping through the bash array elements externally. In the following, the array elements are passed at one shot to awk and accessed within awk using ARGV. Also, there's no reason why awk cannot write to the output file directly

awk -v len="${#myarray[@]}" '
BEGIN{t=ARGC; ARGC-=len; for(i=2; i<t; ++i) b[ARGV[i]]++ };
$4 in b { print > "newfile.txt"}' myfile.txt  "${myarray[@]}"
like image 2
iruvar Avatar answered Oct 18 '22 03:10

iruvar