Jak wydrukować wszystkie kolumny po określonej liczbie za pomocą awk?


90

W powłoce potokuję do awk, gdy potrzebuję określonej kolumny.

Spowoduje to wydrukowanie kolumny 9, na przykład:

... | awk '{print $9}'

Jak mogę powiedzieć awk, żeby wypisał wszystkie kolumny, włączając i po kolumnie 9 , a nie tylko kolumnę 9?


1
możliwy duplikat

Odpowiedzi:


83
awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'

3
kilka drobnych poprawek:awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
glenn jackman

Dzięki @glenn, to rzeczywiście trochę bardziej ogólne. W każdym razie - zdecydowanie się zgodzę, że lepiej byłoby użyć cutlub perldo tego. Używaj tego tylko wtedy, gdy naprawdę nalegasz na to, aby go mieć awk.
Amadan

1
@SiegeX: Nie dodaje bajtów NUL, pozostawia FS na miejscu między każdym pustym polem.
Wstrzymano do odwołania.

1
Zobacz odpowiedź @ Ascherer na elegancję.

3
@veryhungrymike: Elegancja jest fajna, ale wolałbym mieć rację. : p
Amadan

68

Jeśli chcesz wykonać szereg pól, awknie ma na to prostego sposobu. cutZamiast tego polecam :

cut -d' ' -f 9- ./infile

Edytować

Dodano ogranicznik spacji, ponieważ domyślnie jest to tabulator. Dzięki Glenn za wskazanie tego


15
Jedną z rzeczy w wycinaniu jest to, że używa określonego separatora (domyślnie tabulatora), gdzie awk używa „białych znaków”. W przypadku wycięcia 2 kolejne tabulatory ograniczają puste pole.
glenn jackman

1
Jak zauważył @glennjackman, ogranicznikiem awk jest „biały znak” (również dowolna kwota). Zatem ustawienie ogranicznika cięcia na pojedynczą spację również nie pasowałoby do zachowania. niestety pętla jest najlepsza, jaką można zrobić, więc wygląda.
poncha

Ten nie działa poprawnie. Wypróbuj polecenie find . | xargs ls -l | cut -d' ' -f 9-. Z jakiegoś powodu liczone są również podwójne spacje. Przykład: lrwxrwxrwx 1 me me 21 Dec 12 00:00 ./file_a lrwxrwxrwx 1 me me 64 Dec 6 00:06 ./file_bspowoduje./file_a 00:06 ./file_b
Marco Pashkov

@MarcoPashkov proszę rozwinąć Ten nie działa poprawnie , zwłaszcza biorąc pod uwagę, że używasz dokładnie tego samego kodu w swoim potoku. Nawiasem mówiąc, nigdy nie
SiegeX

cięcie nie działa tutaj. Na przykład, jeśli dane wejściowe to „foo bar” (pojedyncza spacja) dla jednej linii i „foo ___ bar” (tj. Wiele spacji, ale SO jest zbyt sprytne, aby to pokazać) dla innej, cut przetworzy je inaczej.
UKMonkey

54
awk '{print substr($0, index($0,$9))}'

Edycja : Uwaga, to nie działa, jeśli jakiekolwiek pole przed dziewiątą zawiera taką samą wartość jak dziewiąta.


3
ten jest genialny!

10
@veryhungrymike: ... i nie działa, jeśli jakiekolwiek pole przed dziewiątą wartością zawiera taką samą wartość jak dziewiąta.
Amadan

6
Prawdopodobnie z powodu klasycznego zdania „miejmy nadzieję, że Twój plik nie zawiera tego problemu”. To absolutne nie-nie w inżynierii s / w stwierdzenie: „nie będziemy tracić czasu na sprawdzanie błędów pod kątem np. Wartości ujemnych, ponieważ„ mamy nadzieję, że użytkownik będzie wystarczająco inteligentny, aby ich nie wypróbować ”, awaria naszego narzędzia „”. HAHAHA! Zawsze miło mi to słyszeć! (I jak poczucie humoru), a także, jak idioci zrobić istnieje, to obowiązkiem dewelopera, aby jego rzeczy idiota-dowód ! Zamiast „liczyć na dobro w człowieku”. To raczej postawa oczekiwana od filozofów, a nie od s / w inżynierów ... LOL
błąd składniowy

3
Nie mówiłem, żeby nie sprawdzać błędów, ale jeśli wiesz, że nie napotkasz problemu, to rozwiązanie jest w porządku, jak powiedziałem. Ale dziękuję za niepotrzebne głosy przeciw @syntaxerror. To rozwiązanie zadziała dla niektórych, jak pokaże (obecnie) 19 głosów za, ale jeśli nie, nie używaj go do swojego rozwiązania. Istnieje wiele sposobów rozwiązania problemu PO.
Ascherer,

1
Jeśli używasz awk w wierszu poleceń w swojej codziennej pracy, jest to zdecydowanie rozwiązanie, którego potrzebujesz. Czy to nie jest oczywiste? Sprawdzanie błędów itp. Nie ma w tym przypadku większego znaczenia, ponieważ wpisujesz go i możesz wyłapać tego typu rzeczy przed naciśnięciem klawisza Enter (osobiście nie sądzę, aby awk i tak było używane do niczego innego, dlatego Mam perl, python, tcl i około 100+ innych, lepszych, szybszych, mniej irytujących języków skryptowych!) Oczywiście, może daję moim kolegom programistom zbyt duży kredyt i naprawdę potrzebują sprawdzania błędów nawet w tym, co piszą w locie (??)
osirisgothra

11
sed -re 's,\s+, ,g' | cut -d ' ' -f 9-

Zamiast zajmować się białymi znakami o zmiennej szerokości, zamień wszystkie białe znaki na pojedynczą spację. Następnie użyj prostego cutz interesującymi polami.

Nie używa awk, więc nie jest normalne, ale wydaje się odpowiednie, biorąc pod uwagę inne odpowiedzi / komentarze.


1
Podaj dokładniejszą odpowiedź, w przeciwnym razie opublikuj to jako komentarz do pytania.
Alper Turan

Jest to idealne do ps faux | użycia. Nigdy nie bój się przyznać, że narzędzie XYZ nie jest najwłaściwsze.
kevinf

10

Ogólnie perl zastępuje awk / sed / grep et. al., i jest znacznie bardziej przenośny (a także po prostu lepszy scyzoryk).

perl -lane 'print "@F[8..$#F]"'

Oczywiście obowiązuje Timtowtdi.


Musisz dodać opcję wiersza poleceń -llub dodać \ndo instrukcji print.
glenn jackman

@glenn jackman: Prawdopodobnie. Nie jest wymagane, jeśli jest częścią innej wiadomości, lub jest przypisane do zmiennej itp. Jeśli chodzi o „lepsze”, perl z pewnością wygląda lepiej w small. Trzeba przyznać, że może wyglądać bardzo nieporządnie.
bobbogo

Nie zrozum mnie źle, lubię Perla. Uwielbiam awk za to, czym jest.
glenn jackman

Moje urządzenie osadzone nie jest dostarczane z Perlem, ale ma awk.
Sepero

Głosowanie w dół, ponieważ pytanie dotyczyło tego, jak to zrobić w awk, a nie w perl, ruby, java, python, bash.
Tom Harrison,

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

To odcina to, co jest przed danym polem nr., N, i wypisuje całą resztę wiersza, łącznie z polem nr N i zachowując oryginalne odstępy (nie zmienia formatowania). Nie ma znaczenia, czy ciąg pola pojawia się również gdzie indziej w wierszu, co jest problemem z odpowiedzią Ascherera.

Zdefiniuj funkcję:

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

I użyj tego w ten sposób:

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

Wyjście zachowuje wszystko, łącznie ze spacjami końcowymi. Dla N = 0 zwraca cały wiersz taki, jaki jest, a dla n> NF pusty łańcuch


To jest dobry pomysł. Nie działa to całkiem na obecnym Macu używającym typowego gawk, ponieważ załamuje się $ 0. Rozwiązaniem jest ustawienie zmiennej na $ 0 w pierwszym kroku, na przykład: '{s = $ 0; ... print substr (s, index (s, m) +1}
joelparkerhenderson

1

Oto przykład ls -lwyniku:

-rwxr-----@ 1 ricky.john  1493847943   5610048 Apr 16 14:09 00-Welcome.mp4
-rwxr-----@ 1 ricky.john  1493847943  27862521 Apr 16 14:09 01-Hello World.mp4
-rwxr-----@ 1 ricky.john  1493847943  21262056 Apr 16 14:09 02-Typical Go Directory Structure.mp4
-rwxr-----@ 1 ricky.john  1493847943  10627144 Apr 16 14:09 03-Where to Get Help.mp4

Moje rozwiązanie do druku cokolwiek postu $9jestawk '{print substr($0, 61, 50)}'



0

Aby wyświetlić pierwsze 3 pola i wydrukować pozostałe pola, możesz użyć:

awk '{s = ""; for (i=4; i<= NF; i++) s= s $i : "; print $1 $2 $3 s}' filename

gdzie 1 $ 2 $ 3 to pierwsze 3 pola.


0
function print_fields(field_num1, field_num2){
    input_line = $0

    j = 1;
    for (i=field_num1; i <= field_num2; i++){
        $(j++) = $(i);

    }
    NF = field_num2 - field_num1 + 1;
    print $0

    $0 = input_line
}

0

Używanie cut zamiast awk i przezwyciężanie problemów z ustalaniem, od której kolumny zacząć, za pomocą polecenia -c znak cut.

Tutaj mówię, podaj mi wszystkie oprócz pierwszych 49 znaków wyniku.

 ls -l /some/path/*/* | cut -c 50-

Na /*/*/końcu polecenia ls mówi, że pokaż mi, co jest również w podkatalogach.

Możesz także wyciągnąć pewne zakresy znaków ala (z wyciętej strony podręcznika). Np. Pokaż nazwy i czasy logowania aktualnie zalogowanych użytkowników:

       who | cut -c 1-16,26-38
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.