How to pass the file name dynamically to awk when awk is used in command substitution to build the shell array?

Tag: unix Author: kenboy988 Date: 2009-09-03

Here is the script I am using and this is working fine

# This is a test file which we are creating and this will be used to create the shell array
cat > test.txt <<End-of-message
1A|1B|1C|1D
2A|2B|2C|2D
3A|3B|3C|3D
4A|4B|4C|4D
End-of-message

set -A col1_arr `awk 'BEGIN { FS = "|" }{print $1}' test.txt`

i=0
while [ $i -lt ${#col1_arr[@]} ]
do
    echo "Column 1 is:${col1_arr[$i]}"
    (( i=i+1 ))
done

rm test.txt # delet the test file

I do not want to hard-code test.txt and want to be able to pass it as a variable. Please advise.

Other Answer1

set -A col1_arr `awk -v file=$myfile -F '|' \
    'END { while (getline < file) print $1 }' /dev/null`

awk will advance to a new record only when the main input stream has a new record. So you have to do the loop manually in an END block, and make sure the awk script reaches the end block by specifying /dev/null as the main input stream.

Other Answer2

It seems you are trying to produce the following output:

Column 1 is: 1A
Column 1 is: 2A
Column 1 is: 3A
Column 1 is: 4A

If that is the case, we don't need that long and complicated series of commands. This will do:

awk -F'|' '{print "Column 1 is: " $1}' test.txt

If you still want to use a variable instead of file name, then set it (example in Bash):

fileName=test.txt
awk -F'|' '{print "Column 1 is: " $1}' $fileName

Other Answer3

We can pass the file name dynamically to awk regardless of awk being used in command substitution, e. g., if the file name is the script's first argument:

... `awk 'BEGIN { FS = "|" }{print $1}' $1`