user3166747
user3166747

Reputation: 284

Piping to awk (Bash)

This code works:

#!bin/bash
ad="J Dt, K R, P MA
A F, E B, R VA
O T, O R, T OK
E A, P Rd, S MA
H S, B R, R MA"
byState() {
    a="$ad"
    h=$(echo "$a" | 
    sed -e 's/ MA/, Massachusetts/' | sed -e 's/ OK/, Oklahoma/' | sed -e 's/ VA/, Virginia/')
    h=$(echo "$h" | awk -F, '{print $4 ", " $0}' $* | sort)
    ... following code
    echo "$h"
}
byState

but if in function byState I replace a="$ad" by a="$1" and I call byState "$ad" I get awk: fatal: cannot open file 'J' for reading (No such file or directory).

Can someone explain this different behavior?

Upvotes: 1

Views: 870

Answers (1)

dave_thompson_085
dave_thompson_085

Reputation: 38866

awk -F, '{script}' $* within function byState() takes the arguments of the function after wordsplitting and globbing and uses them as arguments to awk, and awk treats arguments (other than first when used as the script, and any of the form name=value which are treated as assignments) as filenames to process, which starts by opening them. Since the first token is J and apparently you don't have a file named J in the current directory opening it gives an error.


If you want to use the data in the first argument of byState() as the input to awk, do

 echo "$1" | awk -F, '{script}' # with NO OTHER ARGS to awk

or better

 printf '%s\n' "$1" | ...
 # which reliably won't mangle backslashes and some dashes 

or even better on shells that support it (you didn't identify yours)

awk -F, '{script}' <<<"$1"

Also, awk can do string substitution without any sed, although if you want sed you can do multiple substitutions in one sed. Plus some shells can do string substitution on their own without either sed or awk -- but you didn't ask about doing this right, only what you were doing wrong.

Upvotes: 2

Related Questions