views:

589

answers:

6

I'm writing a bash script to get data from procmail and produce an output CSV file.

At the end, I need to translate from this:

---label1: 123456
---label2: 654321
---label3: 246810
---label4: 135791
---label5: 101010

to this:

label1,label2,label3,label4,label5
123456,654321,246810,135791,101010

I could do this easily with a ruby script but I don't want to call another script other than the bash script. So I've though of doing it with sed.

I can extract the data I want like this:

sed -nr 's/^---(\S+): (\S+)$/\1,\2/p'

But I don't know how to transpose it. Can you help me?

+1  A: 

If you're running sed I'd argue that you are calling another script. So why not write it in Ruby if that's easier to write and maintain?

If you're worried about having multiple files could embed the Ruby code in the bash script as a here document (assuming Ruby can read a script from the Standard Input).

Dave Webb
ruby can read the script from standard input as a here document but I then lose the standard input as data and have to mess with opening files. See my answer to see my final solution as a ruby one-liner.
chmeee
A: 

Perhaps this is what you are looking for? (from unix.com)

num=$(awk -F"," 'NR==1 { print NF }' data)
print $num

i=1
while (( $i > tmpdata
(( i = i + 1 ))
done
mv tmpdata data
Belrog
A: 

Finally I resolved it using ruby, as suggested buy Dave Webb but as a one-liner not a here document with the following script:

ruby -ne 'BEGIN{@head=[];@data=[]}; @head << $1 && @data << $2 if $_.match(/^---(\S+): (\S+)$/); END{puts @head.join(",");puts @data.join(",")}' $FILE

I didn't know that I could use BEGIN, END blocks to set the variables and output the results.

chmeee
A: 

you said you needed bash script..

#!/bin/bash
labels=`awk '/---/{printf("%s,",$1)}' file.txt `
values=`awk '/---/{printf("%s,",$2)}' file.txt `
labels=`echo $labels|sed 's/---//g;s/\://g;s/\,$//'`
values=`echo $values|sed 's/\,$//`
echo $labels
echo $values
Neeraj
A: 

You can do something like this from within the shell script:

cat demo | awk -F':' '{print $1}' | sed -e s/'---'// | tr '\n' ',' > csv_file

cat demo | awk '{print $2}' | tr '\n' ',' >> csv_file

Barun
there is no need for cat. pass the file to awk
ghostdog74
That's true. I agree.
Barun
+1  A: 

you can just do everything in awk

awk 'BEGIN{
    FS=": "
}
{ 
  gsub("---","")
  label[++c] = $1
  num[++d] =$2
}
END{
    for(i=1;i<c;i++){
        printf label[i]","
    }
    print label[c]
    for(i=1;i<d;i++){
        printf num[i]","
    }
    print num[d]    
}' file

output

# ./test.sh
label1,label2,label3,label4,label5
123456,654321,246810,135791,101010

redirect the output to csv file as needed

ghostdog74