2009-07-29 8 views
0

Ich schreibe ein bash Skript, um Daten von procmail zu erhalten und eine Ausgabe CSV-Datei zu erzeugen.Spalte zu Zeile Übersetzung mit sed

Am Ende muss ich von diesem übersetzen:

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

dazu: diese

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

ich tun konnte leicht mit einem ruby Skript, aber ich möchte nicht eine andere nennen Skript anders als das bash Skript. Also habe ich es mit sed gemacht.

kann ich die Daten extrahieren ich so will:

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

Aber ich weiß nicht, wie es transponieren. Kannst du mir helfen?

+0

-r benötigt ist kein Standard –

+0

Ich verstehe nicht den Grund für die Verwendung von Ruby. Sie möchten die Verwendung einer Skriptsprache vermeiden und verwenden daher zwei. Ihr Skript wird wachsen und wachsen, und bevor Sie es wissen, wird es für Schleifen und tr und awk und sed Anrufe überall geben. Die Verwendung einer geeigneten CSV-Bibliothek kann ebenfalls hilfreich sein, wenn nicht jetzt, dann beim nächsten Job, in dem in Ihren Daten Anführungszeichen oder Kommas stehen. Ich weiß nicht über Ruby, aber Perl hat einen. – reinierpost

+0

Die Sache ist, dass ich keine andere Datei wollte, nur ein Bash-Skript, um die Verarbeitung zu machen. Aber ich habe einen Weg gefunden, Ruby als Oneliner im Bash-Skript zu verwenden. – chmeee

Antwort

0

Schließlich beschloß ich, es Rubin verwenden, wie Dave Webb vorgeschlagen kaufen, aber als Einzeiler hier nicht um ein Dokument mit dem folgenden Skript:

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

ich nicht tat weiß, dass ich mit BEGIN, END-Blöcken die Variablen setzen und die Ergebnisse ausgeben kann.

1

Wenn Sie sed ausführen, würde ich argumentieren, dass Sie Aufruf eines anderen Skripts sind. Warum also nicht in Ruby schreiben, wenn das einfacher zu schreiben und zu pflegen ist?

Wenn Sie befürchten, mehrere Dateien zu haben, könnte der Ruby-Code in das Bash-Skript als here document einbetten (vorausgesetzt, Ruby kann ein Skript von der Standardeingabe lesen).

+0

Ruby kann das Skript von der Standardeingabe als ein hier Dokument lesen, aber ich verliere dann die Standardeingabe als Daten und muss mit Eröffnungsdateien herumspielen. Siehe meine Antwort, um meine endgültige Lösung als Rubin-Einzeiler zu sehen. – chmeee

0

Vielleicht suchen Sie das? (von unix.com)

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

i=1 
while (($i > tmpdata 
((i = i + 1)) 
done 
mv tmpdata data
0

Sie sagten, Sie Bash-Skript benötigt ..

 
#!/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 
0

Sie so etwas wie dies aus dem Shell-Skript tun können:

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

catdemo | awk '{print $ 2}' | tr '\ n' '' >> csv_file

+0

gibt es keine Notwendigkeit für Katze. Übergeben Sie die Datei an awk – ghostdog74

+0

Das stimmt. Ich stimme zu. – Barun

1

Sie einfach alles in awk tun können

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 

Ausgang

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

die Ausgabe in CSV-Datei umleiten als