2016-07-09 5 views
0

Ich möchte awk verwenden, um Spalten zu kombinieren, die von der 4. Spalte bis zum Ende der Spalten beginnen.Verwenden Sie awk Befehlszeile, um Spalten zu kombinieren

Eingang:

1 682333 191.858 191517119 C A C A A A C A A A A A 
2 1862626 71.9275 56032940 A C C C A A A C A C A A 
3 11957134 155.78 150230950 B B B B A B A B A B A B 
4 2516482 51.2692 31496569 B A A A A A A A A A A A 
5 9378200 51.2798 31572927 A A B B B A A A A A B A 
6 2071534 52.1573 32824318 A B A B A B A B B B A B 
7 2074633 33.068 19035920 A A B A A A B A B A B A 
8 7856856 121.811 117540910 A A A A A A A A B A B A 
9 3741206 2.18574 2169864 A A A A A A A A A A A A 
10 4411364 12.5959 24191374 C C A C A C C C A C A C 

Ausgang:

1 682333 191.858 191517119 CA  CA  AA  CA  AA  AA 
2 1862626 71.9275 56032940 AC  CC  AA  AC  AC  AA 
3 11957134 155.78 150230950 BB  BB  AB  AB  AB  AB 
4 2516482 51.2692 31496569 BA  AA  AA  AA  AA  AA 
5 9378200 51.2798 31572927 AA  BB  BA  AA  AA  BA 
6 2071534 52.1573 32824318 AB  AB  AB  AB  BB  AB 
7 2074633 33.068 19035920 AA  BA  AA  BA  BA  BA 
8 7856856 121.811 117540910 AA  AA  AA  AA  BA  BA 
9 3741206 2.18574 2169864 AA  AA  AA  AA  AA  AA 
10 4411364 12.5959 24191374 CC  AC  AC  CC  AC  AC 

By the way, wenn es für einen awk Tutorial jede gute Website ist, fügen Sie es hier empfehlen.

+0

Ein Tutorial , könnten Sie mit [\ [this \]] (https://www.gnu.org/software/gawk/manual/gawk.pdf) beginnen. – sjsam

+1

Und nachdem Sie das Tutorial gelesen haben, kommen Sie zurück zur Frage und schreiben Sie, was Sie getan haben, um das Problem zu lösen – sjsam

+0

Kaufen Sie das Buch Effective Awk Programming, 4th Edition, von Arnold Robbins. –

Antwort

3

In meinem Buch ‚One-Liner‘ ist ein Schimpfwort, wenn der Code auf einem einzigen passt Zeile unter ca. 80 Zeichen. Ich denke, awk Code wird leichter verstanden, wenn mehrere Zeilen für mehrere Anweisungen formatiert. Daher habe ich diese marginal unterschiedliche Version des Codes entwickelt. Der Fall, in dem eine ungerade Anzahl von Feldern auf der Linie ist, benötigt keine spezielle Behandlung. Zugriff auf $(NF+1) wird eine leere Zeichenfolge (oder Nullzahl) geben.

awk '{ printf("%s\t%s\t%s\t%s", $1, $2, $3, $4) 
     for (i = 5; i <= NF; i += 2) 
      printf("\t%s%s", $i, $(i+1)) 
     print "" 
    }' data 

Geht man von dem Datenlayout in der Frage, tab Separatoren wurden in den Originaldaten verwendet, aber die Präsentation ist mit tabstops bei 4 Räumen gesetzt. Daher verwendet der Code Registerkarten als Trennzeichen. Ich fügte hinzu, eine zusätzliche Zeile in die Beispieldaten enthält:

11 1111111 22.2222 33333333 D D W W X X Y Y Z Z = 

Der Ausgang I von dem bekam und die Daten in der Frage sahen aus wie diese nach der Formatierung mit tabstops auf 4:

1 682333 191.858 191517119 CA CA AA CA AA AA 
2 1862626 71.9275 56032940 AC CC AA AC AC AA 
3 11957134 155.78 150230950 BB BB AB AB AB AB 
4 2516482 51.2692 31496569 BA AA AA AA AA AA 
5 9378200 51.2798 31572927 AA BB BA AA AA BA 
6 2071534 52.1573 32824318 AB AB AB AB BB AB 
7 2074633 33.068 19035920 AA BA AA BA BA BA 
8 7856856 121.811 117540910 AA AA AA AA BA BA 
9 3741206 2.18574 2169864 AA AA AA AA AA AA 
10 4411364 12.5959 24191374 CC AC AC CC AC AC 
11 1111111 22.2222 33333333 DD WW XX YY ZZ = 
0

Dies kann sehr unordentlich aussehen, sollte aber funktionieren.

awk '{for(i=1; i<=4; i++) {printf "%s ",$i;} for(i=5; i<=NF; i++) {printf "%s", $i; if(i<NF){i++; printf "%s",$i;} printf "\t"} printf "\n"; }' filename 

Hier drucken wir ersten 4 Spalten - mit zwei Raum zwischen ihnen (so dass jeder ursprünglichen Formatierung zwischen ihnen geändert wird) - dann Spalten drucken verbleibenden zwei auf ein und einen Reiter zwischen ihnen Kombinieren (Sie können Tab ändern einige Anzahl)

2

Sehr ähnlich @sps antworten, aber ohne die, ob und unter Verwendung von Tabs

awk '{ printf $1; for (i=2; i<=4; i++) {printf "\t%s",$i}; for (i=5; i<=NF; i+=2) { printf "\t%s%s",$i,$(i+1);} printf "\n"; }' filename 
+0

Versuchen Sie das, wenn die Eingabedatei eine Zeile enthält, die mit "% s" beginnt. Verwenden Sie immer "printf"% s ", $ 1" anstelle von "printf $ 1". Verwenden Sie auch 'print '" 'statt' printf \ \ ", damit Sie Zeilen mit dem aktuellen' ORS' abschließen, anstatt einen Wert hart zu codieren. –

+1

Auf dieser Ebene der Feinsinnigkeit sollte auch OFS anstelle von "\ t" verwendet werden. –

+0

Richtig, tut mir leid, dass ich das verpasst habe. Das Ganze sollte wirklich geschrieben werden als (ungetestet) 'awk -v OFS =' \ t '' {für (i = 1; i <= 4; i ++) printf "% s% s", $ i, OFS; für (; i <= NF; i + = 2) printf "% s% s% s", $ i, $ (i + 1), (i

Verwandte Themen