Take the 2-minute tour ×

I am getting var as argument from shell script to awk

awk -v var = "blah1|blah2|blah3" -f awk_script.awk

I need to put each blah's into a hashset, currently, I am doing it like this. I am getting it into an array and looping through the array and putting it into a hashset. Can I do better like getting the var and putting the variables directly into a hashset instead of parsing the var into an array first?

            dest = arr[i];

down the line, I check

if ( dest in exclusion_destinations )
// do something
share|improve this question
By the way: the first array index from split is 1 (not 0)... –  Peter.O Mar 2 '12 at 17:21
EDITED question. I came to know that when I was testing that it starts from 1. –  user14039 Mar 2 '12 at 19:12

2 Answers 2

up vote 0 down vote accepted

The only construct that sets many array elements at once is the split function (at least in standard awk, GNU awk may have other possibilities). This assigns to numerical indices. So you can't escape a loop if you want to make an associative array.

You can, however, change your exclusion test not to use an array. If the strings to exclude don't contain any regexp special character (().?*+[]\^$), you can treat the value of var as a regexp to match against, with a little tweaking. This may be slightly slower than using an array, but probably not measurably so unless you have a lot of strings to exclude.

BEGIN { exclude = "^(" var ")$" }
match(dest, exclude) { … }

Another approach is to treat var as a concatenation of strings to exclude; dest is to be excluded if is appears in var between |. This will be again slower than a regexp match, but only measurably so for sufficiently large exclusion lists.

BEGIN { exclude = "|" var "|" }
index(dest, exclude) { … }
share|improve this answer

I assume your second "down the line" dest is from an input file which contains values you check against the excluded values (eg. call this input file "data").
You can read in your list of excluded values via another file (eg. called "exclude"). If exclude is already delimited by |, just use sed to change them to \n.

Create test files

sed 's/ /\n/g' <<<"blah1 blah2 abcde" >data
sed 's/|/\n/g' <<<"blah1|blah2|blah3" >exclude

The script

awk '{
  if( NR==FNR ) { exclude[$0]++ 

    # somewhere later on
    # "dest" to be tested is $1 of "data"
    if( exclude[$1] ) print "do something", $1 
}' exclude data

or something like this for passing the 2 "files" may suit.:

}' <(sed 's/|/\n/g' <<<"blah1|blah2|blah3") \


do something blah1
do something blah2
share|improve this answer

Your Answer

