Diese Zeile funktionierte, bis ich im zweiten Feld Leerzeichen hatte.
svn status | grep '\!' | gawk '{print $2;}' > removedProjs
Gibt es eine Möglichkeit, awk alles in $ 2 oder höher drucken zu lassen? ($ 3, $ 4 .. bis wir keine Spalten mehr haben?)
Ich sollte wohl hinzufügen, dass ich dies in einer Windows-Umgebung mit Cygwin mache.
grep | awk
ein Antimuster - Sie wollenawk '/!/ { print $2 }'
svn status | grep '\!' | cut -d' ' -f2- > removedProjs
Antworten:
druckt alle bis auf die erste Spalte:
druckt alle bis auf zwei erste Spalten:
quelle
awk '{$1=""; print substr($0,2)}' input_filename > output_filename
awk -F, -vOFS=, '{$1=""; print $0}'
Sie erhalten ein anfängliches Trennzeichen ($1
ist immer noch enthalten, nur als leere Zeichenfolge). Sie können das aber mit abstreifensed
:awk -F, -vOFS=, '{$1=""; print $0}' | sed 's/^,//'
Es gibt eine doppelte Frage mit einer einfacheren Antwort unter Verwendung von cut:
-d
Gibt den Begrenzer (Leerzeichen) an ,-f
gibt die Liste der Spalten an (alle beginnend mit dem 2.)quelle
awk
Version ausführt , gibt es Probleme mitcut
der Zeilenpufferung , dieawk
nicht auftreten: stackoverflow.com/questions/14360640/…awk
Behandelt mehrere benachbarte Raumzeichen. als einzelnes Trennzeichen, währendcut
dies nicht der Fall ist; auch - obwohl dies im vorliegenden Fall kein Problem ist -cut
akzeptiert nur ein einziges wörtliches Zeichen. als Trennzeichen, währendawk
eine Regex erlaubt.Sie können eine for-Schleife verwenden, um die Druckfelder $ 2 bis $ NF (integrierte Variable, die die Anzahl der Felder in der Zeile darstellt) zu durchlaufen.
Bearbeiten: Da "Drucken" eine neue Zeile anfügt, möchten Sie die Ergebnisse puffern:
Alternativ können Sie printf verwenden:
quelle
'{for(i=11;i<=NF-1;i++){printf "%s ", $i}; print $NF;}'
Keine führenden oder nachfolgenden Leerzeichen.Meine Antwort basiert auf der von VeeArr , aber ich habe festgestellt, dass sie mit einem Leerzeichen begann, bevor die zweite Spalte (und der Rest) gedruckt wurde. Da ich nur einen Reputationspunkt habe, kann ich ihn nicht kommentieren. Hier ist eine neue Antwort:
Beginnen Sie mit "out" als zweiter Spalte und fügen Sie dann alle anderen Spalten hinzu (falls vorhanden). Dies geht gut, solange es eine zweite Spalte gibt.
quelle
Die meisten Lösungen mit awk lassen ein Leerzeichen. Die Optionen hier vermeiden dieses Problem.
Option 1
Eine einfache Schnittlösung (funktioniert nur mit einzelnen Trennzeichen):
Option 2
Wenn Sie eine awk-Neuberechnung erzwingen, entfernen Sie manchmal das hinzugefügte führende Leerzeichen (OFS), indem Sie die ersten Felder entfernen (funktioniert mit einigen Versionen von awk):
Option 3
Durch Drucken jedes mit formatierten Felds erhalten Sie
printf
mehr Kontrolle:Alle vorherigen Antworten ändern jedoch alle wiederholten FS zwischen Feldern in OFS. Lassen Sie uns ein paar Optionen erstellen, die dies nicht tun.
Option 4 (empfohlen)
Eine Schleife mit Sub, um Felder und Trennzeichen an der Vorderseite zu entfernen.
Und mit dem Wert von FS anstelle von Leerzeichen (das geändert werden könnte).
Ist mehr tragbar und löst keine Änderung des FS zu OFS: HINWEIS: Das
^[FS]*
ist eine Eingabe mit führenden Leerzeichen zu akzeptieren.Option 5
Es ist durchaus möglich, eine Lösung zu erstellen, die keine zusätzlichen (führenden oder nachfolgenden) Leerzeichen hinzufügt und vorhandene Leerzeichen mithilfe der Funktion
gensub
von GNU awk wie folgt beibehält:Es kann auch verwendet werden, um eine Gruppe von Feldern bei einer bestimmten Anzahl auszutauschen
n
:In diesem Fall wird das OFS natürlich verwendet, um beide Teile der Zeile zu trennen, und der nachfolgende Leerraum der Felder wird weiterhin gedruckt.
HINWEIS:
[FS]*
wird verwendet, um führende Leerzeichen in der Eingabezeile zuzulassen.quelle
Ich persönlich habe alle oben genannten Antworten ausprobiert, aber die meisten waren etwas komplex oder einfach nicht richtig. Der einfachste Weg, dies aus meiner Sicht zu tun, ist:
Wobei -F "" das Trennzeichen definiert, das awk verwenden soll. In meinem Fall ist das Leerzeichen das Standard-Trennzeichen für awk. Dies bedeutet, dass -F "" ignoriert werden kann.
Wobei NF die Gesamtzahl der Felder / Spalten definiert. Daher beginnt die Schleife vom 4. Feld bis zum letzten Feld / der letzten Spalte.
Wobei $ N den Wert des N-ten Feldes abruft. Daher druckt $ i das aktuelle Feld / die aktuelle Spalte basierend auf der Anzahl der Schleifen.
quelle
lauhub schlug hier diese korrekte, einfache und schnelle lösung vor
quelle
Das irritierte mich so sehr, dass ich mich
cut
hinsetzte und einen ähnlichen Feldspezifikations-Parser schrieb, der mit GNU Awk 3.1.7 getestet wurde.Erstellen Sie zunächst ein neues Awk-Bibliotheksskript
pfcut
mit dem Namen zFügen Sie dann das folgende Skript ein und speichern Sie es. Danach sieht die Verwendung folgendermaßen aus:
Um all das zu vermeiden, denke ich, dass das Beste, was man tun kann (siehe ansonsten Automatisches Laden einer Benutzerfunktion beim Start mit awk? - Unix & Linux Stack Exchange ), das Hinzufügen eines Alias zu
~/.bashrc
; zB mit:... dann können Sie einfach anrufen:
Hier ist die Quelle des
pfcut
Skripts:quelle
cut
, nichtawk
Drucken von Spalten ab # 2 (die Ausgabe hat am Anfang keinen nachgestellten Platz):
quelle
+
nach dem Leerzeichen hinzufügen sollten , da die Felder durch mehr als ein Leerzeichen getrennt sein können (awk
behandelt mehrere benachbarte Leerzeichen als ein einziges Trennzeichen). Außerdemawk
ignoriert Räumen führen, so dass Sie die Regex mit beginnen sollte^[ ]*
. Mit Leerzeichen als Trennzeichen können Sie die Lösung sogar verallgemeinern. Das Folgende gibt beispielsweise alles aus dem 3. Feld zurück:awk '{sub(/^[ ]*([^ ]+ +){2}/, ""); print $0}'
Mit beliebigen Feldtrennzeichen wird es jedoch schwieriger.Würde das funktionieren?
Es lässt jedoch etwas Leerzeichen vor sich.
quelle
Dieser verwendet awk, um alle außer dem letzten Feld zu drucken
quelle
Dies ist, was ich aus allen Empfehlungen bevorzugt habe:
Drucken von der 6. bis zur letzten Spalte.
oder
quelle
Wenn Sie bestimmte Spalten benötigen, die mit einem beliebigen Begrenzer gedruckt werden:
Wenn Sie also Leerzeichen in einer Spalte haben, sind es zwei Spalten, aber Sie können es mit jedem Trennzeichen oder ohne Trennzeichen verbinden.
quelle
Perl-Lösung:
Diese Befehlszeilenoptionen werden verwendet:
-n
Schleife um jede Zeile der Eingabedatei, drucke nicht automatisch jede Zeile-l
Entfernt Zeilenumbrüche vor der Verarbeitung und fügt sie anschließend wieder hinzu-a
Autosplit-Modus - Teilen Sie die Eingabezeilen in das @ F-Array. Standardmäßig wird auf Leerzeichen aufgeteilt-e
Führen Sie den Perl-Code aussplice @F,0,1
Entfernt Spalte 0 sauber aus dem @ F-Arrayjoin " ",@F
Verbindet die Elemente des @ F-Arrays mit einem Leerzeichen zwischen den einzelnen ElementenPython-Lösung:
python -c "import sys;[sys.stdout.write(' '.join(line.split()[1:]) + '\n') for line in sys.stdin]" < file
quelle
Wenn Sie den Teil der Zeile, den Sie nicht abhacken, nicht neu formatieren möchten, ist die beste Lösung, die ich mir vorstellen kann, in meiner Antwort in:
Wie drucke ich alle Spalten nach einer bestimmten Nummer mit awk?
Es zerhackt, was vor der angegebenen Feldnummer N steht, und druckt den gesamten Rest der Zeile, einschließlich der Feldnummer N, und behält den ursprünglichen Abstand bei (es wird nicht neu formatiert). Es spielt keine Rolle, ob die Zeichenfolge des Feldes auch an einer anderen Stelle in der Zeile angezeigt wird.
Definieren Sie eine Funktion:
Und benutze es so:
Die Ausgabe behält alles bei, einschließlich nachfolgender Leerzeichen
In Ihrem speziellen Fall:
Wenn Ihre Datei / Ihr Stream keine Zeilenumbrüche in der Mitte der Zeilen enthält (Sie könnten ein anderes Datensatztrennzeichen verwenden), können Sie Folgendes verwenden:
Der erste Fall schlägt nur in Dateien / Streams fehl, die das seltene hexadezimale Zeichen Nummer 1 enthalten
quelle
Dies würde funktionieren, wenn Sie Bash verwenden und Sie könnten so viele 'x' wie Elemente verwenden, die Sie verwerfen möchten, und es werden mehrere Leerzeichen ignoriert, wenn sie nicht maskiert werden.
quelle
Perl:
quelle
Diese
awk
Funktion gibt einen Teilstring zurück$0
, der Felder vonbegin
bis enthältend
:Um alles ab Feld 3 zu bekommen:
Um einen Abschnitt davon zu erhalten
$0
, werden die Felder 3 bis 5 abgedeckt:b, e, p, i
Unsinn in der Funktionsparameterliste ist nur eineawk
Möglichkeit, lokale Variablen zu deklarieren.quelle
Ich möchte die vorgeschlagenen Antworten auf die Situation erweitern, in der Felder möglicherweise durch mehrere Leerzeichen begrenzt sind - der Grund, warum das OP
cut
vermutlich nicht verwendet .Ich weiß, dass das OP gefragt hat
awk
, abersed
hier würde ein Ansatz funktionieren (Beispiel beim Drucken von Spalten vom 5. bis zum letzten):Pure Sed Ansatz
Erläuterung:
s///
wird standardmäßig zur Substitution verwendet^\s*
Entspricht einem aufeinanderfolgenden Leerzeichen am Zeilenanfang\S+\s+
bedeutet eine Datenspalte (Nicht-Leerzeichen, gefolgt von Leerzeichen)(){4}
bedeutet, dass das Muster viermal wiederholt wird.sed und schneiden
indem Sie nur aufeinanderfolgende Leerzeichen durch eine einzelne Registerkarte ersetzen;
tr und cut:
tr
kann mit der Option auch verwendet werden, um aufeinanderfolgende Zeichen zu quetschen-s
.quelle
Awk-Beispiele sehen hier komplex aus, hier ist die einfache Bash-Shell-Syntax:
Wo
1
zählt Ihre n- te Spalte von 0?Beispiel
Angesichts dieses Inhalts von file (
in.txt
):Hier ist die Ausgabe:
quelle
Ich war mit keiner der
awk
hier vorgestellten Lösungen zufrieden , weil ich die ersten Spalten extrahieren und dann den Rest drucken wollte, also wandte ich michperl
stattdessen an. Der folgende Code extrahiert die ersten beiden Spalten und zeigt den Rest unverändert an:Der Vorteil gegenüber der
perl
Lösung von Chris Koknat besteht darin, dass tatsächlich nur die ersten n Elemente von der Eingabezeichenfolge abgespalten werden. Der Rest der Saite ist überhaupt nicht geteilt und bleibt daher vollständig intakt. Mein Beispiel zeigt dies mit einer Mischung aus Leerzeichen und Tabulatoren.Um die Anzahl der zu extrahierenden Spalten zu ändern, ersetzen Sie die
3
im Beispiel durch n + 1.quelle
Von dieser Antwort ist nicht schlecht, aber der natürliche Abstand ist weg.
Bitte vergleichen Sie es dann mit diesem:
Dann würden Sie den Unterschied sehen.
Selbst
ls -la | awk '{$1=$2=""; print}'
was auf der bisher am besten gewählten Antwort basiert, behält die Formatierung nicht bei.Daher würde ich Folgendes verwenden und es erlaubt am Anfang auch explizite selektive Spalten:
Beachten Sie, dass jedes Leerzeichen auch für Spalten zählt. Im Folgenden sind beispielsweise die Spalten 1 und 3 leer, 2 ist INFO und 4 ist:
quelle
Wenn Sie formatierten Text möchten, verketten Sie Ihre Befehle mit echo und drucken Sie mit $ 0 das letzte Feld.
Beispiel:
Drucke:
quelle
Wegen einer falschen, am besten bewerteten Antwort mit 340 Stimmen habe ich gerade 5 Minuten meines Lebens verloren! Hat jemand diese Antwort ausprobiert, bevor er sie bewertet hat? Anscheinend nicht. Völlig nutzlos.
Ich habe ein Protokoll, in dem nach $ 5 mit einer IP-Adresse mehr Text oder kein Text sein kann. Ich brauche alles von der IP-Adresse bis zum Ende der Leitung, sollte es nach 5 Dollar etwas geben. In meinem Fall ist dies tatsächlich ein awk-Programm, kein awk-Oneliner, also muss awk das Problem lösen. Wenn ich versuche, die ersten 4 Felder mit der am besten bewerteten, aber völlig falschen Antwort zu entfernen:
es spuckt eine falsche und nutzlose Antwort aus (ich habe [..] hinzugefügt, um zu demonstrieren):
Es gibt sogar einige Vorschläge, um Substr mit dieser falschen Antwort zu kombinieren. So ist Komplikation eine Verbesserung.
Wenn die Spalten eine feste Breite haben, bis der Schnittpunkt und awk benötigt werden, lautet die richtige Antwort:
welches die gewünschte Ausgabe erzeugt:
quelle