Pokazany plik ma wszystkie szczegóły w jednym wierszu:
name : farah age : 23 phone number : 0123 education : degree
Założyłem, że możesz na stałe wpisać kod age :do polecenia itp., Ale następujący po nim tekst będzie się różnił, a szczegóły mogą nie być w podanej kolejności lub być ciągłe.
Można wyodrębnić części linii z grep„s -oflagi. Drukuje tylko dopasowaną część, a nie całą linię.
Jeśli chcesz dołączyć części age :i phone number :, możesz użyć -eflagi, aby określić wiele dopasowań lub naprzemiennie.
$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123
Wyrażenie [^ ]*oznacza dowolną liczbę znaków, które nie są spacjami, więc dopasowuje znaki po age :maksymalnie spacji.
Zamień filena nazwę pliku zawierającego twoje dane. Możesz zapisać nowy plik, przekierowując dane wyjściowe do nowego pliku za pomocą >operatora, w następujący sposób:
grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile
Gdy to zrobisz, nie zobaczysz żadnych wyników. Najpierw sprawdź dane wyjściowe, a następnie dodaj przekierowanie.
Oto przykład z naprzemiennością. Używamy -Eflagi, aby powiedzieć grepo rozszerzonym wyrażeniu regularnym. Składnia jest (pattern1|pattern2)taka - pasuje pattern1i / lub pattern2. Jeśli którykolwiek zostanie znaleziony, zostanie wydrukowany (niezależnie od tego, czy drugi zostanie znaleziony, czy nie). Teraz używam +znaczenia co najmniej jednego z poprzedzających znaków, zamiast *oznaczać zero lub więcej poprzedzających znaków. W tym kontekście oba działają równie dobrze.
$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23
phone number : 0123
Jeśli chcesz pominąć części age :i phone number:, możesz użyć -Pflagi, aby poprosić grepo użycie wyrażeń regularnych zgodnych z Perl. Obsługuje to naprzemienność, a także sposób dopasowywania tekstu po danym wzorcu:
$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123
Jeśli chcesz sformatować tekst inaczej, możesz użyć sedna przykład:
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
To zależy od tego, czy agenadejdzie wcześniej phone number, więc dostosuj odpowiednio, jeśli tak nie jest. Jeśli nie możesz polegać na zamówieniu, możesz użyć tego bardzo skomplikowanego polecenia:
$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23
To phone number :zmienia kolejność linii, tak aby sekcja była pierwsza na każdej linii, a następnie dokonuje drugiej zamiany, aby wybrać pożądane szczegóły. Technikę zastosowaną tutaj zawdzięczam Muru .
Uwagi na temat sedpoleceń nieobjętych poprzednimi objaśnieniami
-rużyj rozszerzonego wyrażenia regularnego dla bardziej czytelnych poleceń (GNU sedrozumie -Eto samo znaczenie)
s/old/new/wymienić oldznew
(pattern)zapisuje się w patterncelu późniejszego użycia, za pomocą \1lub \2etc (zgodnie z kolejnością od lewej do prawej, w której występują grupy przechwytywania - zwróć uwagę, że sedpomieści tylko 7 z nich!).
.dowolny znak, dlatego .*reprezentuje dowolną liczbę dowolnych znaków.
; rozdziela polecenia, jak w powłoce.