2016-07-30 8 views
2

Ich habe eine Zeile csv mit vielen Elementen. Jetzt möchte ich nach jedem n-ten Element in einem Bash/Shell-Skript einen Zeilenumbruch einfügen.Shell-Befehl zum Einfügen einer neuen Zeile jedes n-te Element einer großen Reihe von durch Komma getrennten Strings

Bonus: Ich möchte eine Zeile mit Deskriptoren voranstellen und die Anzahl der Deskriptoren als 'n' verwenden.

Beispiel:

"4908041eee3d4bf98e606140b21ebc89.16","7.38974601030349731","45.31298584267982221","94ff11ce7eb54642b0768dde313e8b25.16","7.38845318555831909","45.31425320325949713", (...) 

in

"id","lon","lat" 
"4908041eee3d4bf98e606140b21ebc89.16","7.38974601030349731","45.31298584267982221" 
"94ff11ce7eb54642b0768dde313e8b25.16","7.38845318555831909","45.31425320325949713" 
(...) 

Edit: Ich habe einen ersten Versuch, aber die Komma-Trennzeichen fehlen dann:

(...) | xargs --delimiter=',' -n3 

"4908041eee3d4bf98e606140b21ebc89.16" "7.38974601030349731" "45.31298584267982221" 
"94ff11ce7eb54642b0768dde313e8b25.16" "7.38845318555831909" "45.31425320325949713" 

versucht, die "" zu ersetzen mit ","

(...) | xargs --delimiter=',' -n3 -i echo ${{}//" "/","} 
-bash: ${{}//\": bad substitution 
+1

uns Zeigen Sie, was Sie versucht. – Fazlin

+0

| xargs --delimiter = ',' -n3 aber das entfernt die Kommas – mstra001

+0

Bearbeiten Sie Ihre Post und fügen Sie den Befehl und die Ausgabe, die Sie bekommen, so dass Sie Hilfe bekommen können Debugging/Fixing – Fazlin

Antwort

3

Hinweis: Diese Lösung unterscheidet die Anzahl der Ausgabespalten von der Anzahl der Spalten in der Kopfzeile.

Unter der Annahme, dass die Felder in Ihrem CSV-Eingang haben keine eingebettet, Instanzen (in dem Fall, dass Sie einen richtigen CSV-Parser bräuchten), versuchen awk:

awk -v RS=, -v header='"id","lon","lat"' ' 
    BEGIN { 
    print header 
    colCount = 1 + gsub(",", ",", header) 
    } 
    { 
    ORS = NR % colCount == 0 ? "\n" : "," 
    print 
    } 
' file.csv 

Beachten Sie, dass, wenn die Eingabedatei endet mit einem Newline (wie es typisch ist), erhalten Sie einen zusätzlichen Zeilenumbruch hinter dem Ausgang.

Mit GNU Awk oder Mawk (aber nicht BSD/OSX Awk, die nur wörtlichen, Einzelzeichen RS Werte unterstützt), können Sie dieses Problem zu beheben, wie folgt:

awk -v RS='[,\n]' -v header='"id","lon","lat"' ' 
    BEGIN { 
    print header 
    colCount = 1 + gsub(",", ",", header) 
    } 
    { 
    ORS = NR % colCount == 0 ? "\n" : "," 
    print 
    } 
' file.csv 

BSD/OS X Awk Workaround: Bleiben Sie mit -v RS=, und ersetzen Sie file.csv durch <(tr -d '\n' < file.csv), um alle Zeilenumbrüche aus dem Eingang zuerst zu entfernen.

4

Ich würde mit Perl dafür gehen!

Nehmen wir an, das so etwas wie Ihre Datei ausgibt:

printf "1,2,3,4,5,6,7,8,9,10" 

1,2,3,4,5,6,7,8,9,10 

Dann könnten Sie diese verwenden, wenn Sie bei jeder 4. Komma ersetzt wollte:

printf "1,2,3,4,5,6,7,8,9,10" | perl -pe 's{,}{++$n % 4 ? $& : "\n"}ge' 
1,2,3,4 
5,6,7,8 
9,10 
+0

Das gleiche hier :), ich würde mit Perl für das gehen :) –

3
cat data.txt | xargs -n 3 -d, | sed 's/ /,/g' 

Mit n = 3 hier und Eingabedateiname heißt data.txt

+0

++ für eine pragmatische Lösung, die den Lösungsversuch des OPs behebt; Allgemeiner Vorbehalt: funktioniert nur, wenn die Eingabefelder keine eingebetteten Leerzeichen haben (was offensichtlich für die OP-Daten gilt). – mklement0

2

Ihre Eingabedatei Angenommen wird input genannt:

echo id,lon,lat; awk '{ORS=NR%3?",":"\n"}1' RS=, input