grep 'potato:' file.txt | sed 's/^.*: //'
grep
szuka dowolnego wiersza zawierającego ciąg potato:
, a następnie dla każdego z tych wierszy sed
zastępuje ( s///
- podstawia) dowolny znak ( .*
) od początku wiersza ( ^
) do ostatniego wystąpienia ciągu :
(dwukropek, po którym następuje spacja) pustym string ( s/...//
- zastąp pierwszą część drugą częścią, która jest pusta).
lub
grep 'potato:' file.txt | cut -d\ -f2
Dla każdej linii, która zawiera potato:
, cut
podzieli linię na wiele pól oddzielonych spacją ( -d\
- d
= separator, \
= znak spacji ze znakiem ucieczki, coś podobnego -d" "
też by zadziałało) i wypisze drugie pole każdej takiej linii ( -f2
).
lub
grep 'potato:' file.txt | awk '{print $2}'
Dla każdego wiersza, który zawiera potato:
, awk
wypisze drugie pole ( print $2
), które jest domyślnie rozdzielone spacjami.
lub
grep 'potato:' file.txt | perl -e 'for(<>){s/^.*: //;print}'
Wszystkie wiersze, które zawierają, potato:
są wysyłane do skryptu Perl inline ( -e
), który pobiera wszystkie wiersze z , a następnie dla każdego z tych wierszy dokonuje takiego samego podstawienia jak w pierwszym przykładzie powyżej, a następnie drukuje go.stdin
lub
awk '{if(/potato:/) print $2}' < file.txt
Plik jest wysyłany przez stdin
( < file.txt
wysyła zawartość pliku przez stdin
polecenie po lewej stronie) do awk
skryptu, który dla każdego wiersza zawierającego potato:
( if(/potato:/)
zwraca wartość true, jeśli wyrażenie regularne /potato:/
pasuje do bieżącego wiersza), wypisuje drugie pole, zgodnie z opisem powyżej.
lub
perl -e 'for(<>){/potato:/ && s/^.*: // && print}' < file.txt
Plik jest wysyłany za pośrednictwem stdin
( < file.txt
patrz wyżej) do skryptu Perl, który działa podobnie do powyższego, ale tym razem upewnia się również, że każda linia zawiera ciąg potato:
( /potato:/
jest to wyrażenie regularne, które pasuje, jeśli bieżąca linia zawiera potato:
, robi ( &&
), a następnie przechodzi do zastosowania wyrażenia regularnego opisanego powyżej i wyświetla wynik).
awk '$1 ~ /potato/ { print $2 }' file.txt
.awk '/potato:/ {print $2}'
perl -pe
Lub użyj asercji wyrażenia regularnego:
grep -oP '(?<=potato: ).*' file.txt
źródło
-o
oznacza drukowanie tylko pasującej części wiersza. Podczas gdy-P
wnioskuje o wyrażeniu regularnym zgodnym z Perlem, które jest dodatnim wyrażeniem regularnym typu lookbehind(?<=string)
.Można myśleć o Grepie jako o ograniczonym Sed lub o Sedie jako o uogólnionym Grepie. W tym przypadku Sed to dobre, lekkie narzędzie, które robi to, co chcesz - chociaż oczywiście istnieje również kilka innych rozsądnych sposobów, aby to zrobić.
źródło
Spowoduje to wydrukowanie wszystkiego po każdym dopasowaniu, tylko w tej samej linii:
Zrobi to samo, z wyjątkiem tego, że wypisze również wszystkie kolejne wiersze:
Używane są następujące opcje wiersza polecenia:
-n
pętla wokół każdego wiersza pliku wejściowego-l
usuwa nowe wiersze przed przetworzeniem i dodaje je później-e
wykonać kod perlaźródło
-P
użyć wyrażenia regularnego Perla-o
aby wyświetlić tylko dopasowanie\s
aby dopasować spację popotato:
\K
pominąć dopasowanie.*
aby dopasować resztę ciągu (ów)źródło
Możesz użyć grep, jak podają inne odpowiedzi. Ale nie potrzebujesz grep, awk, sed, perl, cut ani żadnego zewnętrznego narzędzia. Możesz to zrobić za pomocą czystego basha.
Spróbuj tego (średniki są tam, aby umożliwić umieszczenie wszystkiego w jednym wierszu):
## mówi bashowi, aby usunął najdłuższe dopasowanie „:” w linii $ od początku.
lub jeśli chciałeś mieć klucz zamiast wartości, %% mówi bashowi, aby usunął najdłuższe dopasowanie „:” w linii $ od końca.
Podciąg do podziału to „: \”, ponieważ znak spacji musi być poprzedzony ukośnikiem odwrotnym.
Więcej takich znajdziesz w projekcie dokumentacji Linuksa .
źródło
while read
jest bardzo powolny; użycie zewnętrznego narzędzia będzie w rzeczywistości znacznie szybsze, o ile wybierzesz takie z buforowanym I / O (tj. praktycznie każde z wymienionych w tej odpowiedzi i wiele innych).read -r
chyba że potrzebujesz jakiegoś raczej nieznośnego zachowania sprzed POSIX.Nowoczesny BASH obsługuje wyrażenia regularne:
while read -r line; do if [[ $line =~ ^potato:\ ([0-9]+) ]]; then echo "${BASH_REMATCH[1]}" fi done
źródło