2013-05-17 12 views
49

Na przykład mam plik:Jak mogę dostać ostatnie słowo w każdej linii z bash

$ cat file 

i am the first example. 

i am the second line. 

i do a question about a file. 

i muszę:

example, line, file 

í intencyjny z "awk", ale problem jest że słowa są w innej przestrzeni

+0

Twoja „druga linia” nie jest w drugiej linii z powodu pustych linii, proszę podać mniej dwuznaczne przykłady w przyszłości. –

Odpowiedz

55

Spróbuj

$ awk 'NF>1{print $NF}' file 
example. 
line. 
file. 

Aby uzyskać wynik w jednej linii, jak w przykładzie, spróbuj:

{ 
    sub(/\./, ",", $NF) 
    str = str$NF 
} 
END { print str } 

wyjściowa:

$ awk -f script.awk file 
example, line, file, 

P bash:

$ while read line; do [ -z "$line" ] && continue ;echo ${line##* }; done < file 
example. 
line. 
file. 
+1

+1, usunięto moją podobną odpowiedź. – anubhava

+0

Po prostu ... niesamowite. – MrPickles

+0

@Fredrik Pihl, czy możesz dodać wyjaśnienia do każdej sekcji kodu, na przykład: "ten kod wypisuje ostatnie pole odebrane przez awk, drukując' $ NF' "? –

20

można zrobić coś takiego w awk:

awk '{ print $NF }' 

Edit: Aby uniknąć pusty wiersz:

awk 'NF{ print $NF }' 
+1

To również wydrukuje puste linie –

+1

dzięki za pomoc =) –

4

istnieje wiele sposobów. jak pokazuje awk rozwiązanie, to jest czyste rozwiązanie

sed rozwiązaniem jest usunięcie czegokolwiek do ostatniego miejsca. Więc jeśli nie ma miejsca na końcu, to powinno działać

sed 's/.* //g' <file>

można uniknąć sed również i pójść na while pętli.

while read line 
do [ -z "$line" ] && continue ; 
echo $line|rev|cut -f1 -d' '|rev 
done < file 

odczytuje wiersz, przegląda go, obcina pierwszy (tj.Ostatnia w oryginale) i przywraca z powrotem

samo można zrobić w czystym sposób bash

while read line 
do [ -z "$line" ] && continue ; 
echo ${line##* } 
done < file 

nazywane jest ekspansja parametr

+0

zobacz mój bash, żeby jakoś zignorować puste linie ... –

+0

@FredrikPihl niesamowity :) Nauczyłem się nowej sztuczki: D – abasu

9

Kolejny sposób to zrobić w zwykłym bash wykorzystuj? komenda rev tak:

cat file | rev | cut -d" " -f1 | rev | tr -d "." | tr "\n" "," 

Zasadniczo, można odwrócić wiersze w pliku, a następnie podzielić się nimi z cut wykorzystania przestrzeni jako separator, podjąć pierwsze pole, które cut produkuje, a potem znowu odwrócić żeton, użyj tr -d ponownie usunąć niechciane znaki i tr zastąpić nowej linii znaków z ,

Ponadto, można uniknąć pierwszego kota wykonując:

rev < file | cut -d" " -f1 | rev | tr -d "." | tr "\n" "," 
49

można to łatwo zrobić z grep:

grep -oE '[^ ]+$' file 

(-E Użyj rozszerzonych wyrażeń regularnych; -o wyprowadza tylko dopasowany tekst zamiast pełnej linii)

+1

Podoba mi się ten najlepszy =] – Ken

+0

be 'grep -oE '[^] + $'', chcesz zobaczyć kartę tutaj ze względu na zachowanie przeglądarki, ale tak czy inaczej, to rozważa również spacje tabulacji, albo jeszcze lepiej możesz zrobić 'grep -oE '[^ [: spacja:]] + $ '' –

3

tldr;

$ awk '{print $NF}' file.txt | paste -sd, | sed 's/,/, /g' 

Dla pliku jak ten

$ cat file.txt 
The quick brown fox 
jumps over 
the lazy dog. 

dana komenda wypisze

fox, over, dog. 

Jak to działa:

  • awk '{print $NF}': drukuje ostatnie pole każdej linii
  • paste -sd,: czyta stdin seryjnie (-s jeden plik na raz) i zapisuje pola oddzielone przecinkami (-d,)
  • sed 's/,/, /g': s ubstitutes "," z ", "g lobally (dla wszystkich instancji)

Referencje:

+0

Podczas gdy ten kod może odpowiedzieć na pytanie, podanie dodatkowego kontekstu dotyczącego _why_ i/lub _how_ tego kodu odpowiedziałoby na pytanie, które znacznie poprawiłoby jego długoterminową wartość: . Proszę [edytuj] swoją odpowiedź, aby dodać wyjaśnienie w postaci . –

Powiązane problemy