Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linux csv file concatenate columns into one column

I've been looking to do this with sed, awk, or cut. I am willing to use any other command-line program that I can pipe data through.

I have a large set of data that is comma delimited. The rows have between 14 and 20 columns. I need to recursively concatenate column 10 with column 11 per row such that every row has exactly 14 columns. In other words, this:

a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p

will become:

a,b,c,d,e,f,g,h,i,jkl,m,n,o,p

I can get the first 10 columns. I can get the last N columns. I can concatenate columns. I cannot think of how to do it in one line so I can pass a stream of endless data through it and end up with exactly 14 columns per row.

Examples (by request):

How many columns are in the row?

sed 's/[^,]//g' | wc -c

Get the first 10 columns:

cut -d, -f1-10

Get the last 4 columns:

rev | cut -d, -f1-4 | rev

Concatenate columns 10 and 11, showing columns 1-10 after that:

awk -F',' ' NF { print $1","$2","$3","$4","$5","$6","$7","$8","$9","$10$11}'
like image 877
kainaw Avatar asked Jan 03 '23 16:01

kainaw


2 Answers

Awk solution:

awk 'BEGIN{ FS=OFS="," }
     { 
         diff = NF - 14;
         for (i=1; i <= NF; i++)
             printf "%s%s", $i, (diff > 1 && i >= 10 && i < (10+diff)?
                                 "": (i == NF? ORS : ",")) 
     }' file

The output:

a,b,c,d,e,f,g,h,i,jkl,m,n,o,p
like image 92
RomanPerekhrest Avatar answered Jan 05 '23 15:01

RomanPerekhrest


With GNU awk for the 3rd arg to match() and gensub():

$ cat tst.awk
BEGIN{ FS="," }
match($0,"(([^,]+,){9})(([^,]+,){"NF-14"})(.*)",a) {
    $0 = a[1] gensub(/,/,"","g",a[3]) a[5]
}
{ print }

$ awk -f tst.awk file
a,b,c,d,e,f,g,h,i,jkl,m,n,o,p
like image 33
Ed Morton Avatar answered Jan 05 '23 16:01

Ed Morton