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
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.
@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.
@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.
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.
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}
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:
Odpowiedzi:
awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'
źródło
awk -v N=9 '{sep=""; for (i=N; i<=NF; i++) {printf("%s%s",sep,$i); sep=OFS}; printf("\n")}'
cut
lubperl
do tego. Używaj tego tylko wtedy, gdy naprawdę nalegasz na to, aby go miećawk
.Jeśli chcesz wykonać szereg pól,
awk
nie ma na to prostego sposobu.cut
Zamiast tego polecam :cut -d' ' -f 9- ./infile
Edytować
Dodano ogranicznik spacji, ponieważ domyślnie jest to tabulator. Dzięki Glenn za wskazanie tego
źródło
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_b
spowoduje./file_a 00:06 ./file_b
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.
źródło
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
cut
z interesującymi polami.Nie używa awk, więc nie jest normalne, ale wydaje się odpowiednie, biorąc pod uwagę inne odpowiedzi / komentarze.
źródło
ps faux |
użycia. Nigdy nie bój się przyznać, że narzędzie XYZ nie jest najwłaściwsze.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.
źródło
-l
lub dodać\n
do instrukcji print.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
źródło
Oto przykład
ls -l
wyniku:Moje rozwiązanie do druku cokolwiek postu
$9
jestawk '{print substr($0, 61, 50)}'
źródło
ruby -lane 'print $F[3..-1].join(" ")' file
źródło
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.
źródło
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 }
źródło
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.
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:
źródło