Pass an array to awk that contains the column numbers to print

I have a CSV file ( usvd.csv ) that contains 41 columns, my bash script processes the header row to train which columns are printed, as a result I need to print 26 out of 41 columns. They may vary - The number of columns in the CSV and the number of columns to print.

An array containing the number of columns 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 41 columns, I only want to print the columns listed above, and they may differ from file to file.

Thanks!!

+6
source share
2 answers

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 will lead to

 1,2,4,6 
+3
source

I like the @devnull solution, but for completeness I 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 fields separated by spaces.
  • -vd="$list" passes the variable bash $list to awk, which will be used as d .
  • BEGIN{split(d, a, " ")} splits the string d into pieces by space, so [1] = field1, a [2] = field2, ...
  • {for (i in a) printf "%s ", $(a[i]); printf "\n"}' {for (i in a) printf "%s ", $(a[i]); printf "\n"}' loops and prints.
+6
source

Source: https://habr.com/ru/post/956638/


All Articles