Poniżej znajduje się tekst w pliku:
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
Muszę grep dla „42B” i uzyskać wynik z powyższego tekstu, takiego jak:
Pseudo name=Apple
Code=42B
state=fault
Czy ktoś ma pomysł, jak to osiągnąć za pomocą grep
/ awk
/ sed
?
Odpowiedzi:
Z
awk
RS=
zmienia separator rekordów wejściowych z nowej linii na puste linie. Jeśli którekolwiek pole w rekordzie zawiera/42B/
wydrukuj rekord.''
(ciąg zerowy) to magiczna wartość używana do reprezentowania pustych linii zgodnie z POSIX :Akapity wyjściowe nie zostaną rozdzielone, ponieważ separator wyjściowy pozostaje pojedynczą nową linią. Aby upewnić się, że między akapitami wyjściowymi jest pusta linia, ustaw separator rekordów wyjściowych na dwie nowe linie:
źródło
FILENAME
), nie jest złym pomysłem stosowanie przekierowania, ponieważ pozwala to uniknąć problemów z nazwą pliku=
lub jego początkiem-
(lub istnieniem-
), powoduje pojawienie się spójnych komunikatów o błędach i pozwala uniknąć uruchamianiaawk
lub wykonywania inne przekierowania, jeśli nie można otworzyć pliku wejściowego.Zakładając, że dane mają taką strukturę, że zawsze jest to linia przed i po tym, możesz chcieć użyć przełączników grep
-A
(po) i-B
(przed), aby powiedzieć mu, aby zawierała 1 linię przed dopasowaniem i 1 linię po niej:Jeśli chcesz mieć te same linie liczb przed i po wyszukiwaniu, możesz użyć przełącznika
-C
(kontekstowego):Jeśli chcesz być bardziej rygorystyczny podczas dopasowywania wielu linii, możesz użyć narzędzia
pcregrep
, aby dopasować wzór do wielu linii:Powyższy wzór odpowiada następująco:
-M
- wiele linii'Pseudo.*\n.*42B.*\nstate.*'
- dopasowuje grupę ciągów, w których pierwszy ciąg zaczyna się od słowa,"Pseudo"
po którym następuje dowolny znak do końca linii\n
, następnie dowolne znaki do łańcucha,"42B"
po którym następują dowolne znaki do następnego końca linii (\n
), a następnie ciąg"state"
a następnie dowolne znaki.źródło
-C
(kontekst) może być używany jako skrót, jeśli-A
i-B
są takie same.Prawdopodobnie istnieje podobnie podobny sposób na awk, ale w Perlu:
To w zasadzie mówi o podzieleniu pliku na części ograniczone pustymi liniami, a następnie wydrukowaniu tylko tych części, które pasują do wyrażenia regularnego.
źródło
cat
;perl -00 -ne 'print if /42B/' file
grep
Niektórych smaków Unix mieć-p
flagę „ust”. Wiem, że robi to AIX .zrobiłby dokładnie to, o co prosisz. YMMV i GNU grep nie mają tej flagi.
źródło
Inne rozwiązanie perla, bez końcowej pustej linii:
Przykład
źródło
perl -00 -ne 'print if /42B/' file
.