Ich habe mehrere Dateien mit jeweils unterschiedlicher Spaltenanzahl. Ich möchte sie konvertieren, um sie in eine Datenbank einzufügen.
Zum Beispiel die Datei test01:
0001 000000000000001 john smith 45 500 0002 000000000000002 peter jackson 20 80 0003 000000000000002 robert brown 35 100 0004 000000000000007 sarah white 40 300
Meine gewünschte Ausgabe lautet:
("0001","000000000000001","john smith","45","500"), ("0002","000000000000002","peter jackson","20","80"), ("0003","000000000000002","robert brown","35","100"), ("0004","000000000000007","sarah white","40","300");
Um dies zu erreichen, verwende ich das folgende Skript:
cat test01 |awk -F"\t" "{print "("\"""$1""\"","\"""$2""\"","\"""$3""\"","\"""$4""\"","\"""$5""\""),"}" |sed "$ s/.$/;/"
Und es funktioniert gut, Das Problem ist, wenn ich eine andere Datei mit einer anderen Anzahl von Spalten finde, daher muss ich das Skript manuell ändern.
Ich weiß, dass ich die Anzahl der Spalten mit der Variablen NF des AWK erhalten kann, aber wie Um diese Variable mit einer for-Schleife im Skript zu kombinieren?
Wenn ich versuche
cat test01 | awk "{for (i = 1; i <= NF; i++){print $i""\"","\"""}}"
, erhalte ich folgendes Ergebnis:
0001"," 000000000000001"," john"," smith"," 45"," 500"," 0002"," 000000000000002"," peter"," jackson"," 20"," 80"," 0003"," 000000000000002"," robert"," brown"," 35"," 100"," 0004"," 000000000000007"," sarah"," white"," 40"," 300","
Kommentare
- Gibt es in der Originaldatei ein Tabulatortrennzeichen oder nur " einige Leerzeichen "?
- Es ist ein Tabulatortrennzeichen
Antwort
Verwenden von GNU sed
:
$ sed -e "s/^/("/" -e "s/\t/","/g" -e "s/$/"),/" -e "$s/.$/;/" file ("0001","000000000000001","john smith","45","500"), ("0002","000000000000002","peter jackson","20","80"), ("0003","000000000000002","robert brown","35","100"), ("0004","000000000000007","sarah white","40","300");
Die -Skript besteht aus vier Teilen:
-
s/^/("/
ersetzt den Zeilenanfang durch("
. -
s/\t/","/g
ersetzt Registerkarten durch","
. Dies ist das Bit, für das GNUsed
erforderlich ist. Fügen Sie für anderesed
-Implementierungen anstelle von\t
eine Literal-Registerkarte ein. -
s/$/"),/
ersetzt das Zeilenende durch"),
. -
$s/.$/;/
ersetzt das Komma am Ende von letzte Zeile (nur) mit;
.
Kommentare
- Ich führe das Skript aus und es fordert " > " auf, etwas zu erwarten
- @ user3333911 Ich hatte nicht übereinstimmende Anführungszeichen aus einer früheren Version. Jetzt behoben und getestet.
Antwort
Wenn Ihre Eingabedatei durch Tabulatoren getrennt ist, können Sie Folgendes versuchen:
awk -F"\t" -vq=""" -vOFS="","" "$1=$1 {print "(" q $0 q ");"}" filename
Oder binden Sie Anführungszeichen in die Druckfunktion ein:
awk -F"\t" -vOFS="","" "$1=$1 {print "(" "\x27" $0 "\x27" ");"}" filename
Kommentare
- Beachten Sie die Kommas am Ende aller Zeilen mit Ausnahme der letzten …
- Gute Nachricht dort @Kusalananda. Ich habe eine schnelle Lösung wie in
awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q "),"}' filename | sed '$s/,$/;/'
durchgeführt. Gibt es einen besseren Vorschlag? - Nein, ' ist eine gute Lösung.
Antwort
Um mit Ihrem ursprünglichen Skript das gleiche Verhalten wie zu erreichen, können Sie die „printf“ -Methode von awk verwenden. Es ermöglicht die Beseitigung von Zeilenumbrüchen, die durch „Drucken“ gesetzt werden. Ich vermute, Ihr Skript sollte folgendermaßen umgeschrieben werden:
cat test01 | awk "{for (i = 1; i <= NF; i++){printf $i""\"","\"""}; printf "\n";}"