Gregg
Gregg

Reputation: 335

Pass array to awk which contains the column numbers which need to be printed

I have a CSV file (usvd.csv) which contains 41 columns, my bash script process the headers row to workout which columns to print, the result is I need to print 26 of the 41 columns. These can differ - The number of columns in the CSV and or the number of columns that need to be printed.

The array the contains the number of columns that need to be printed is as follows:

${UNIQUE[@]} = 1 2 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 21 26 30 35 37 39 40 41

So out of the 41 columns I only want to print the columns listed above and they can differ from file to file.

Thanks!!

Upvotes: 7

Views: 2209

Answers (2)

fedorqui
fedorqui

Reputation: 289745

I like @devnull's solution, but just for completeness I will suggest an awk version:

$ list=$(echo "${UNIQUE[@]}")
$ awk -vd="$list" 'BEGIN{split(d, a, " ")} {for (i in a) printf "%s ", $(a[i]); printf "\n"}' file
col3 col4 col7 
col3 col4 col7 
col3 col4 col7 

For a given file

col1 col2 col3 col4 col5 col6 col7
col1 col2 col3 col4 col5 col6 col7
col1 col2 col3 col4 col5 col6 col7

Explanation

  • list=$(echo "${UNIQUE[@]}") converts the array into a string with space separated fields.
  • -vd="$list" passes the bash variable $list to awk to be used as d.
  • BEGIN{split(d, a, " ")} splits the d string into pieces by space, so that a[1]=field1, a[2]=field2, ...
  • {for (i in a) printf "%s ", $(a[i]); printf "\n"}' loops and prints.

Upvotes: 6

devnull
devnull

Reputation: 123508

You can use cut. Consider the following example:

UNIQUE=(1 2 4 6)          # Array containing columns to be printed
fields=$( IFS=, echo "${UNIQUE[@]}")      # Get the fields in comma-delimited form
# seq -s, 10 would print the string: 1,2,3,4,5,6,7,8,9,10
seq -s, 10 | cut -d, -f"${fields[@]}"     # Print the desired fields

This would results in

1,2,4,6

Upvotes: 4

Related Questions