2015-04-09 17 views
6

Mam plik tekstowy z kilkoma kolumnami tekstu i wartości. Ta struktura:Scalenie dwóch kolumn pliku tekstowego w systemie Linux

CAR  38 
    DOG 42 
CAT  89 
CAR  23 
    APE 18 

Jeśli kolumna 1 ma ciąg znaków, kolumna 2 nie ma (lub faktycznie jest to ciąg do opróżniania). I odwrotnie: jeśli kolumna 1 jest pusta, kolumna 2 ma ciąg. Innymi słowy, "obiekt" (CAR, CAT, DOG itp.) Występuje w kolumnie 1 lub kolumnie 2, ale nigdy w obu.

szukam skuteczny sposób skonsolidować kolumny 1 i 2 tak, że plik wygląda tak zamiast:

CAR 38 
DOG 42 
CAT 89 
CAR 23 
APE 18 

mogę to zrobić w skrypcie bash przy użyciu chwilę, a jeśli, ale "Na pewno jest prostszy sposób robienia tego. Czy ktoś może pomóc?

Pozdrawiam! Z

+0

Strony podręcznika dla 'cut' i' paste' spring to mind. –

+1

'while read; do echo $ ODPOWIEDŹ; done Cyrus

+0

'printf"% s% s \ n "$ ( Cyrus

Odpowiedz

17

Spróbuj tego:

column -t file 

wyjściowy:

 
CAR 38 
DOG 42 
CAT 89 
CAR 23 
APE 18 
8

Uwaga: Jeżeli:

  • szukasz wyjścia z auto wielkości, wyrównany do lewej kolumny o stałej szerokości (najdłuższa wartość pola określa szerokość, z krótszymi wartościami gett ing prawym spacjami)
  • i są zadowoleni z dwie przestrzenie jako separator kolumn
  • i korzystania plików wystarczająco małe, aby czytać w pamięci jako całość,

korzystanie Cyrus's simpler, column-based answer.

Zobacz poniżej, jak porównanie podejścia opartego na column porównuje do poniższego podejścia opartego na awk pod względem wydajności i zużycia zasobów.


awk jest Twój przyjaciel tutaj:

awk -v OFS=' ' '{ print $1, $2 }' file 
  • awk oddziela linie w pole spacjami domyślnie tak, ze swoim wejściu, linie takie jak CAR 38 i DOG 42 są przetwarzane tak samo (CAR i DOG stają się polami 1, $1 i 38 i 42 b ecome field 2, $2).
  • -v OFS=' ' ustawia separator pola wynikowego na dwie spacje (domyślnie jest to pojedyncza spacja); pamiętaj, że nie będzie żadnych wartości wyjściowych, aby utworzyć wyrównanewyjściowe.

Aby utworzyć wyrównane wyjście z polami o różnej szerokości, należy printf funkcji AWK, która daje większą kontrolę nad wyjściem; na przykład po wyjściu 10-char szeroki wyrównany do lewej Kolumna 1 i 2, char szeroki wyrównany do prawej Kolumna 2:

awk '{ printf "%-10s %2s\n", $1, $2 }' file 
  • Należy zauważyć, że szerokość Kolumna musi być z góry znana.
  • W przeciwieństwie do tego, column -t wygodnie określa szerokości kolumn automatycznie, najpierw analizując wszystkie dane, ale ma to wpływ na wydajność i zużycie zasobów; patrz poniżej.

Porównanie wydajności/zasobów zużycie między column -t i podejścia Awk:

  • column -t potrzeby analizowania wszystkich danych wejściowych z przodu, w pierwszym przejeździe, tak aby być w stanie określić maksymalna szerokość kolumn wejściowych; z tego, co mogę powiedzieć, robi to, najpierw czytając dane wejściowe jako całość do pamięci, co może być problematyczne w przypadku dużych plików wejściowych.
  • Natomiast rozwiązanie awk czyta linie jeden po drugim - ale polega na znajomości szerokości kolumn przed czasem.

Zatem

  • column -t będzie zużywają pamięci proporcjonalny do wielkości wejściowych, natomiast awk użyje stałą ilość pamięci.
  • column -t jest zazwyczaj zwykle wolniejszy, w zależności od zastosowanej wersji Awk; mawk jest znacznie szybszy, gawk nieco szybszy, BSD awk jest wolniejszy (!); wyniki oparte na 10-milionowym pliku wejściowym linii; komendy działają na OS X 10.10.2 i Ubuntu 14.04.
+1

Wielkie dzięki! Bardzo dobre rzeczy! – Zooma

Powiązane problemy