Ich habe eine Datei im folgenden Format
Spalte1 Spalte2 str1 1 str2 2 str3 3
Ich möchte, dass die Spalten neu angeordnet werden. Ich habe es unter dem Befehl versucht
cut -f2,1 file.txt
Der Befehl ordnet die Spalten nicht neu an. Irgendeine Idee, warum es nicht funktioniert?
Danke dir.
cut
dass dieser intuitive Befehl zum Nachbestellen nicht unterstützt wird. Ein weiterer Tipp: Sie könnenawk
's-FS
und-OFS
Optionen verwenden, um benutzerdefinierte Eingabe- und Ausgabefeldtrennzeichen (wie-d
und--output-delimiter
fürcut
) zu verwenden.FS
ist eine Option,OFS
ist eine Variable. zBawk -v OFS=";" -F"\t" '{print $2,$1}'
| sed 's/\r//' |
vor demawk
awk '{print $4 "\t" $2 "\t" $6 "\t" $7}' file
Sie können auch kombinieren
cut
undpaste
:über Kommentare: Es ist möglich, Bashismen zu vermeiden und eine Instanz des Schnitts zu entfernen, indem Sie Folgendes tun:
quelle
cut
funktioniert gut für Spalten mit variabler Länge, solange Sie ein eindeutiges Spaltentrennzeichen haben.bash
Ismen zu vermeiden und eine Instanz zu entfernen,cut
indem Siepaste file.txt file.txt | cut -f2,3
mit nur der Schale,
quelle
"$col2"
und"$col1"
- die Daten können Shell-Metazeichen oder andere Spielereien enthalten.Sie können Perl dafür verwenden:
Der Vorteil von Perl besteht darin, dass Sie (wenn Sie Perl kennen) viel mehr Berechnungen für F durchführen können, als Spalten neu anzuordnen.
quelle
perl -ae print
funktioniert wiecat
bei mirVerwenden von
join
:Anmerkungen:
-t $'\t'
In GNUjoin
das intuitivere-t '\t'
ohne das$
Versagen ( coreutils v8.28 und früher?); Es ist wahrscheinlich ein Fehler, dass eine Problemumgehung wie$
notwendig sein sollte. Siehe: Unix Join Separator char .join
benötigt zwei Dateinamen, obwohl nur eine Datei bearbeitet wird. Wenn Sie zweimal denselben Namen verwendenjoin
, wird die gewünschte Aktion ausgeführt.Für Systeme mit geringen Ressourcen ist der
join
Platzbedarf geringer als bei einigen der in anderen Antworten verwendeten Tools:quelle
Ich habe gerade an etwas sehr Ähnlichem gearbeitet, bin kein Experte, aber ich dachte, ich würde die Befehle, die ich verwendet habe, teilen. Ich hatte eine mehrspaltige CSV, für die ich nur 4 Spalten benötigte, und dann musste ich sie neu anordnen.
Meine Datei war Pipe '|' abgegrenzt, aber das kann ausgetauscht werden.
Zugegeben, es ist wirklich rau und fertig, aber es kann angepasst werden!
quelle
Mit sed
Verwenden Sie sed mit den verschachtelten Unterausdrücken grundlegender regulärer Ausdrücke, um den Spalteninhalt zu erfassen und neu zu ordnen. Dieser Ansatz eignet sich am besten, wenn wie in diesem Fall nur eine begrenzte Anzahl von Schnitten zum Neuordnen von Spalten vorhanden ist.
Die Grundidee besteht darin, interessante Teile des Suchmusters mit
\(
und zu umgeben\)
, die im Ersatzmuster wiedergegeben werden können, wobei\#
wobei#
die sequentielle Position des Unterausdrucks im Suchmuster dargestellt wird.Beispielsweise:
Ausbeuten:
Text außerhalb eines Unterausdrucks wird gescannt, aber nicht für die Wiedergabe in der Ersatzzeichenfolge beibehalten.
Obwohl in der Frage keine Spalten mit fester Breite erörtert wurden, werden wir hier darauf eingehen, da dies ein würdiges Maß für jede gestellte Lösung ist. Nehmen wir der Einfachheit halber an, dass die Datei durch Leerzeichen getrennt ist, obwohl die Lösung für andere Trennzeichen erweitert werden kann.
Reduzierende Räume
Um die einfachste Verwendung zu veranschaulichen, nehmen wir an, dass mehrere Leerzeichen zu einzelnen Leerzeichen zusammengefasst werden können und die Werte der zweiten Spalte mit EOL (und nicht mit Leerzeichen aufgefüllt) abgeschlossen werden.
Datei:
Verwandeln:
Spaltenbreiten erhalten
Erweitern wir die Methode nun auf eine Datei mit Spalten konstanter Breite, während Spalten unterschiedliche Breiten haben können.
Datei:
Verwandeln:
Obwohl das Beispiel der Frage keine ungleich langen Zeichenfolgen enthält, unterstützt dieser sed-Ausdruck diesen Fall.
Datei:
Verwandeln:
Vergleich mit anderen Methoden der Spaltenumordnung unter der Schale
Überraschenderweise eignet sich awk für ein Dateimanipulationswerkzeug nicht zum Schneiden von einem Feld bis zum Ende der Aufzeichnung. In sed kann dies mit regulären Ausdrücken erreicht werden, z. B.
\(xxx.*$\)
woxxx
ist der Ausdruck, der mit der Spalte übereinstimmt.Das Verwenden von Einfügen und Ausschneiden von Subshells wird bei der Implementierung in Shell-Skripten schwierig. Code, der über die Befehlszeile funktioniert, kann nicht analysiert werden, wenn er in ein Shell-Skript eingefügt wird. Zumindest war dies meine Erfahrung (die mich zu diesem Ansatz geführt hat).
quelle