Nie próbuj do tego używać grep, zamiast tego użyj awk. Aby dopasować 2 wyrażenia regularne R1 i R2 w grep, można by pomyśleć, że będzie to:
grep 'R1.*R2|R2.*R1'
w awk będzie to:
awk '/R1/ && /R2/'
ale co jeśli R2nakłada się na podzbiór lub jest jego podzbiorem R1? To polecenie grep po prostu nie zadziałałoby, podczas gdy polecenie awk. Powiedzmy, że chcesz znaleźć wiersze zawierające thei heat:
$ echo 'theatre' | grep 'the.*heat|heat.*the'
$ echo 'theatre' | awk '/the/ && /heat/'
theatre
Musisz do tego użyć 2 grepsa i fajki:
$ echo 'theatre' | grep 'the' | grep 'heat'
theatre
i oczywiście, jeśli rzeczywiście wymagałeś ich oddzielności, zawsze możesz napisać w awk ten sam wyrażenie regularne, którego używałeś w grep, i istnieją alternatywne rozwiązania awk, które nie wymagają powtarzania wyrażeń regularnych w każdej możliwej sekwencji.
Odkładając to na bok, co jeśli chcesz rozszerzyć swoje rozwiązanie, aby pasowało do 3 wyrażeń regularnych R1, R2 i R3. W grep byłby to jeden z tych złych wyborów:
grep 'R1.*R2.*R3|R1.*R3.*R2|R2.*R1.*R3|R2.*R3.*R1|R3.*R1.*R2|R3.*R2.*R1' file
grep R1 file | grep R2 | grep R3
podczas gdy w awk byłoby zwięzłe, oczywiste, proste, wydajne:
awk '/R1/ && /R2/ && /R3/'
A jeśli teraz chcesz dopasować dosłowne ciągi znaków S1 i S2 zamiast wyrażeń regularnych R1 i R2? Po prostu nie możesz tego zrobić w jednym wywołaniu grep, musisz albo napisać kod, aby uciec od wszystkich metazarów RE przed wywołaniem grep:
S1=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< 'R1')
S2=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< 'R2')
grep 'S1.*S2|S2.*S1'
lub ponownie użyj 2 greps i fajki:
grep -F 'S1' file | grep -F 'S2'
które znowu są złymi wyborami, podczas gdy w awk po prostu używasz operatora łańcuchowego zamiast operatora wyrażenia regularnego:
awk 'index($0,S1) && index($0.S2)'
Co teraz, jeśli chcesz dopasować 2 wyrażenia regularne w akapicie zamiast w wierszu? Nie można tego zrobić w grep, trywialny w awk:
awk -v RS='' '/R1/ && /R2/'
Co powiesz na cały plik? Znowu nie można tego zrobić w grep i trywialnym w awk (tym razem używam GNU awk dla wieloznakowego RS dla zwięzłości, ale nie jest to dużo więcej kodu w żadnym awk lub możesz wybrać znak kontrolny, o którym wiesz, że nie będzie być na wejściu, aby RS zrobił to samo):
awk -v RS='^$' '/R1/ && /R2/'
Więc - jeśli chcesz znaleźć wiele wyrażeń regularnych lub ciągów w linii, akapicie lub pliku, nie używaj grep, użyj awk.