461 Stimmen

Mit awk alle Spalten von der n-ten bis zur letzten Spalte ausgeben

Diese Zeile funktionierte, bis ich Leerzeichen im zweiten Feld hatte.

svn status | grep '\!' | gawk '{print $2;}' > removedProjs

Gibt es eine Möglichkeit, awk alles in $2 oder größer 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 tue.

2voto

Chris Koknat Punkte 3032

Perl-Lösung:

perl -lane 'splice @F,0,1; print join " ",@F' file

Diese Befehlszeilenoptionen werden verwendet:

  • -n Schleife um jede Zeile der Eingabedatei, nicht automatisch jede Zeile drucken

  • -l entfernt die Zeilenumbrüche vor der Verarbeitung und fügt sie anschließend wieder ein

  • -a Autosplit-Modus - teilt Eingabezeilen in das @F-Array. Standardmäßig wird bei Leerzeichen aufgeteilt

  • -e den Perl-Code ausführen

splice @F,0,1 entfernt sauber die Spalte 0 aus dem Array @F

join " ",@F fügt die Elemente des Arrays @F zusammen, wobei zwischen den einzelnen Elementen ein Leerzeichen eingefügt wird


Python-Lösung:

python -c "import sys;[sys.stdout.write(' '.join(line.split()[1:]) + '\n') for line in sys.stdin]" < file

1voto

Robert Vila Punkte 221

Wenn Sie den Teil der Zeile, den Sie nicht abschneiden, nicht neu formatieren wollen, ist die beste Lösung, die mir einfällt, in meiner Antwort in:

Wie drucke ich alle Spalten nach einer bestimmten Zahl mit awk?

Es schneidet den Teil vor der angegebenen Feldnummer N ab und druckt den Rest der Zeile, einschließlich der Feldnummer N und unter Beibehaltung der ursprünglichen Abstände (es wird nicht neu formatiert). Es spielt keine Rolle, ob die Zeichenfolge des Feldes auch an anderer Stelle in der Zeile erscheint.

Definieren Sie eine Funktion:

fromField () { 
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}

Und verwenden Sie es so:

$ echo "  bat   bi       iru   lau bost   " | fromField 3
iru   lau bost   
$ echo "  bat   bi       iru   lau bost   " | fromField 2
bi       iru   lau bost 

Die Ausgabe behält alles bei, einschließlich nachfolgender Leerzeichen

In Ihrem speziellen Fall:

svn status | grep '\!' | fromField 2 > removedProjs

Wenn Ihre Datei/ihr Stream keine Zeilenumbrüche in der Mitte der Zeilen enthält (Sie könnten ein anderes Satztrennzeichen verwenden), können Sie es verwenden:

awk -v m="\x0a" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'

Der erste Fall schlägt nur bei Dateien/Streams fehl, die die seltene hexadezimale Zeichennummer 1 enthalten

1voto

wonder.mice Punkte 6676

Ce site awk Funktion gibt Teilzeichenfolge von $0 die Felder von begin a end :

function fields(begin, end,    b, e, p, i) {
    b = 0; e = 0; p = 0;
    for (i = 1; i <= NF; ++i) {
        if (begin == i) { b = p; }
        p += length($i);
        e = p;
        if (end == i) { break; }
        p += length(FS);
    }
    return substr($0, b + 1, e - b);
}

Um alles von Feld 3 aus zu erhalten:

tail = fields(3);

Um einen Abschnitt von $0 die die Felder 3 bis 5 abdeckt:

middle = fields(3, 5);

b, e, p, i Unsinn in der Funktionsparameterliste ist nur ein awk Art und Weise der Deklaration lokaler Variablen.

0voto

Sie können es viel einfacher machen:

 svn status | [m/g]awk   '/!/*sub("^[^ \t]*[ \t]+",_)'

 svn status |   [n]awk '(/!/)*sub("^[^ \t]*[ \t]+",_)'

Übernimmt automatisch die Pflege der grep früher im Rohr, sowie das Abschneiden von zusätzlichen FS nach Ausblendung $1 mit dem zusätzlichen Vorteil, dass der Rest der ursprünglichen Eingabe unangetastet bleibt, anstatt dass Tabulatoren mit Leerzeichen überschrieben werden (es sei denn, dies ist der gewünschte Effekt)

Wenn Sie sich sehr sicher sind $1 keine Sonderzeichen enthält, die mit einem Regex escaped werden müssen, ist es noch einfacher:

mawk         '/!/*sub($!_"[ \t]+",_)'
gawk -c/P/e '/!/*sub($!_"""[ \t]+",_)' 

Oder wenn Sie die Anpassung bevorzugen FS+OFS um das alles zu bewältigen:

mawk 'NF*=/!/' FS='^[^ \t]*[ \t]+' OFS='' # this version uses OFS

0voto

kenorb Punkte 134883

Awk-Beispiele sehen hier kompliziert aus, hier ist eine einfache Bash-Shell-Syntax:

command | while read -a cols; do echo ${cols[@]:1}; done

Wo 1 ist Ihr n Spalte von 0 an gezählt.


Beispiel

Angesichts dieses Inhalts der Datei ( in.txt ):

c1
c1 c2
c1 c2 c3
c1 c2 c3 c4
c1 c2 c3 c4 c5

Hier ist die Ausgabe:

$ while read -a cols; do echo ${cols[@]:1}; done < in.txt 

c2
c2 c3
c2 c3 c4
c2 c3 c4 c5

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X