Ich versuche, die 7. Spalte meiner csv-Datei mit an das Ende zu verschieben
awk -F '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}',OFS= "$file"
Dabei ist $ file eine CSV-Datei in einem Verzeichnis. Die Ausgabe ist jedoch
awk: ^ syntax error
Weiß jemand, wie man diesen Fehler behebt?
text-processing
awk
rmb
quelle
quelle
^
gibt den spezifischen Teil des Befehls an, an dem der Fehler aufgetreten ist.Antworten:
Die
-F
Option benötigt ein Argument:-F,
zum Beispiel.Das Ende des
awk
Skripts muss durch ein(Leerzeichen) mit den restlichen Parametern getrennt werden.
Wenn das Feldtrennzeichen ist
,
und Sie es behalten möchten und wenn die Anzahl der Spalten konstant und kleiner oder gleich 11 ist, versuchen Sie Folgendes:quelle
command file > newfile && mv newfile file
. Das sei gesagt, neuere Version von GNUawk
dies zu unterstützen:gawk -i inplace '{blah blah}' file
.mv newfile file
verwendencat newfile > file ; rm -f newfile
- dies bewahrt den Inode und die Berechtigungen vonfile
.mktemp
temporäre Dateinamen in Skripten zu verwenden, anstatt sie hart zu codieren. zBtf=$(mktemp) ; command file > "$tf" ; cat "$tf" > file ; rm -f "$tf"
Kürzere Lösung wäre
Ich bin mir nicht sicher, ob
,+
es in allenawk
Versionen funktionieren wird, aber es funktioniert zumindest in GNU awk, auch im-c
Kompatibilitätsmodus.Erläuterung:
$(NF+1)=$7
: Zuerst fügen wir das 7. Feld am Ende der Zeile hinzu (könnte$12=$7
in diesem Fall sein)$7=""
: im nächsten Schritt wird das 7. Feld gelöscht (die umgebenden Begrenzer bleiben jedoch erhalten)$0=$0
) mehrere Kommas getrennt behandeln (dies über getan wird-F',+'
, hier+
bedeutet ein oder mehrere Male) und auch aktuelle Datensatz über neu ordnen ,$1=$1
um Kraft den Wiederaufbau der Linie mit zuvor eingestellten Ausgabefeld Trennzeichen (durch eine Option gesetzt-v OFS=,
)1
Beispiel Eingabe:
Ausgabe
quelle
,+
sollte also funktionieren.all,ball,call,,,fall
→all,ball,call,fall
). (2)$(NF+1)=$7
ist ein kluger Ansatz. IMHO$0 = $0 OFS $7
ist ein bisschen klarer, nur ein paar Zeichen länger und es scheint dasselbe zu tun. Können Sie sich eine Situation vorstellen, in der$0 = $0 OFS $7
nicht das Gleiche wie in Ihrem Code geschieht?$0=$0 OFS $7
ist wahrscheinlich identisch mit$(NF+1)=$7
, aber nur mit dem Rest des Codes unverändert, nicht im Allgemeinen.Wenn Sie mit drucken
OFS=
, also ohne Trennzeichen zwischen den Feldern, können Sie einfach den Wert von$7
in einer Variablen speichern ,$7
auf leer setzen und die Zeile und die Variable direkt drucken. Sie müssen nicht alle Felder angeben:quelle
Sie meinen wahrscheinlich:
quelle
awk
nie die einfachen Anführungszeichen in siehtOFS=''
, nicht wahr? Sie können genauso gut einfach tippenOFS=
; es ist genau das gleiche.Sie haben nicht ausdrücklich angegeben, dass Sie awk verwenden möchten, und Sie haben angegeben, dass Sie die von bereitgestellte In-Place-Bearbeitung verwenden möchten. Daher
sed -i
hier einesed -i
Variante. Normalerweiseawk
ist es besser, mit Spalten zu arbeiten, aber in diesem Fall bevorzuge ichsed
, weil es natürlich eine beliebige Anzahl von Spalten verarbeitet.Erläuterung:
-r
wählt erweiterte reguläre Ausdrücke aus, um viele umgekehrte Schrägstriche zu vermeidenNatürlich funktioniert dies nicht mit Dateien, die Kommas in Anführungszeichen verbergen (oder, schlimmer noch, sie maskieren), aber awk wird das auch nicht ohne ernsthafte Akrobatik schaffen. Wenn Sie dieses Problem haben, sind Sie mit dem
perl
ModulText:CSV
oder dempython
Modul besser drancsv
.quelle
Einige
awk
Varianten (vorausgesetzt, Ihre Datei befindet sich in der Variablen$file
)Hier können Sie die gesamte Spalte durchlaufen, mit dem Feldtrennzeichen (OFS) drucken und das Satzendezeichen (ORS) am Ende der Zeile drucken.
Hier mit einem regulären Ausdruck und der
gensub()
FunktionTötung der 7 - ten Feld und es am Ende der Zeile zu drucken.
$0
ist der ganze Rekord$n
ist der n- te RekordNF
ist die Anzahl der Felder der aktuellen ZeileOFS
das Ausgabefeld TrennzeichenORS
das Ausgabesatz-Abschlusszeichen1
ist der Trick, um awk zu sagentrue
und den default ($0
) zu drucken .Aktualisieren ...
Ich habe fast vergessen, dass es möglich ist, alle Spalten nach der siebten zu verschieben.
quelle
OFS $7
wohl robuster als"," $7
. (2) Ich halte das", " $7
für falsch, sofern aus der Frage hervorgeht, dass das OP keine Leerzeichen nach den Kommas will. (Und wenn die Eingabedaten Leerzeichen nach den Kommas enthielten,$7
würde dies bereits mit einem Leerzeichen beginnen, und Sie würden ein zusätzliches hinzufügen.)OFS $7
, nicht nur robuster, sondern auch allgemeiner ( "Eile macht Verschwendung" )