简体   繁体   中英

Use bash variable as array in awk and filter input file by comparing with array

I have bash variable like this:

val="abc jkl pqr"

And I have a file that looks smth like this:

abc   4   5
abc   8   8
def   43  4
def   7   51
jkl   4   0
mno   32  2
mno   9   2
pqr   12  1

I want to throw away rows from file which first field isn't present in the val:

abc   4   5
abc   8   8
jkl   4   0
pqr   12  1

My solution in awk doesn't work at all and I don't have any idea why:

awk -v var="${val}" 'BEGIN{split(var, arr)}$1 in arr{print $0}' file

Just slice the variable into array indexes :

awk -v var="${val}" 'BEGIN{split(var, arr)
                           for (i in arr) 
                               names[arr[i]]
                     }
                     $1 in names' file

As commented in the linked question, when you call split() you get values for the array, while what you want to set are indexes. The trick is to generate another array with this content.

As you see $1 in names suffices, you don't have to call for the action {print $0} when this happens, since it is the default.

As a one-liner:

$ awk -v var="${val}" 'BEGIN{split(var, arr); for (i in arr) names[arr[i]]} $1 in names' file
abc   4   5
abc   8   8
jkl   4   0
pqr   12  1
grep -E "$( echo "${val}"| sed 's/ /|/g' )" YourFile

# or

awk -v val="${val}" 'BEGIN{gsub(/ /, "|",val)} $1 ~ val' YourFile

Grep:

  • it use a regex (extended version with option -E ) that filter all the lines that contains the value. The regex is build OnTheMove in a subshell with a sed that replace the space separator by a | meaning OR

Awk:

  • use the same princip as the grep but everything is made inside (so no subshell)
  • use the variable val assigned to the shell variable of the same name
  • At start of the script (before first line read) change the space, (in val ) by | with BEGIN{gsub(/ /, "|",val)}
  • than, for every line where first field (default field separator is space/blank in awk, so first is the letter group) matching, print it (defaut action of a filter with $1 ~ val .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM