Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!!

like image 651
Gregg Avatar asked Oct 24 '13 11:10

Gregg


People also ask

How to print values in awk?

To print a blank line, use print "" , where "" is the empty string. To print a fixed piece of text, use a string constant, such as "Don't Panic" , as one item. If you forget to use the double-quote characters, your text is taken as an awk expression, and you will probably get an error.

How do I print two columns in awk?

We can also print multiple columns and insert our custom string in between columns. For example, to print the permission and filename of each file in the current directory, use the following set of commands: $ ls -l | awk '{ print $1 " : " $8 }' -rw-r--r-- : delimited_data.

Which of the following is used to print number of fields in awk?

The for loop is used to print the column values, and the loop includes three steps. The NF variable indicates the total numbers of fields or columns of the file.


2 Answers

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.
like image 126
fedorqui 'SO stop harming' Avatar answered Sep 21 '22 01:09

fedorqui 'SO stop harming'


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
like image 24
devnull Avatar answered Sep 24 '22 01:09

devnull