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 -o
flagi. Drukuje tylko dopasowaną część, a nie całą linię.
Jeśli chcesz dołączyć części age :
i phone number :
, możesz użyć -e
flagi, 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ń file
na 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 -E
flagi, aby powiedzieć grep
o rozszerzonym wyrażeniu regularnym. Składnia jest (pattern1|pattern2)
taka - pasuje pattern1
i / 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ć -P
flagi, aby poprosić grep
o 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ć sed
na przykład:
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
To zależy od tego, czy age
nadejdzie 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 sed
poleceń nieobjętych poprzednimi objaśnieniami
-r
użyj rozszerzonego wyrażenia regularnego dla bardziej czytelnych poleceń (GNU sed
rozumie -E
to samo znaczenie)
s/old/new/
wymienić old
znew
(pattern)
zapisuje się w pattern
celu późniejszego użycia, za pomocą \1
lub \2
etc (zgodnie z kolejnością od lewej do prawej, w której występują grupy przechwytywania - zwróć uwagę, że sed
pomieści tylko 7 z nich!).
.
dowolny znak, dlatego .*
reprezentuje dowolną liczbę dowolnych znaków.
;
rozdziela polecenia, jak w powłoce.