Nie jest jasne, czego chcesz. new line at the beginningjest pustą linią i new line at endma zastosowanie do każdej linii w pliku. Czy możesz zamieścić przykład?
PP,
3
Właściwie możesz po prostu użyć $. Jest nieco ograniczona, ale nadaje się do użytku w prostych przypadkach.
Przynajmniej GNU grep ma opcję -z, która sprawia, że grep łamie linie za pomocą znaku null. Jednak wydaje się, że nie obsługuje nowej linii lub \ n we wzorcu, aby dopasować nową linię, zobacz raport o błędzie .
jarno
1
@jarno Obsługuje \ nw wzorach z flagą -P
rubystallion
92
spróbuj pcregrepzamiast zwykłego grep:
pcregrep -M "pattern1.*\n.*pattern2" filename
ta -Mopcja umożliwia dopasowanie w wielu wierszach, więc możesz wyszukiwać nowe wiersze jako \n.
-Pjest rozszerzeniem GNU. Mogę go używać, gdy sytuacja tego wymaga (zwykle lookahead / lookbehind), ale POSIX grep może to zrobić tylko z plikiem [[:space:]].
jordanm
1
Strony podręcznika grep FWIW, Solaris i BSD (nie sprawdzały innych), oba mają akapit dla -P. GNU i tak jest dość standardowe. :)
K3 --- rnc
1
Ze strony podręcznika: [-P] Ta opcja nie jest obsługiwana we FreeBSD.
Jeśli chodzi o obejście problemu (bez używania nieprzenośnego -P), możesz tymczasowo zastąpić znak nowego wiersza innym i zmienić go z powrotem, np:
grep -o "_foo_" <(paste -sd_ file) | tr -d '_'
Zasadniczo szuka dokładnego dopasowania, _foo_gdzie _oznacza \n(więc __= \n\n). Nie musisz go tłumaczyć z powrotem tr '_' '\n', ponieważ każdy wzór i tak zostałby wydrukowany w nowej linii, więc _wystarczy usunąć .
przepraszam za moją ignorancję, ale czy użycie podstawienia procesu nie jest kolejną funkcją niezgodną z POSIX, a więc nieprzenośną? w powłoce posix nie mogłem zrobić <(p paste -sd_ file )?
new line at the beginning
jest pustą linią inew line at end
ma zastosowanie do każdej linii w pliku. Czy możesz zamieścić przykład?$
. Jest nieco ograniczona, ale nadaje się do użytku w prostych przypadkach.Odpowiedzi:
grep
wzorce są dopasowywane do poszczególnych wierszy, więc nie ma możliwości dopasowania wzorca do nowej linii znalezionej w danych wejściowych.Możesz jednak znaleźć puste wiersze w ten sposób:
grep '^$' file grep '^[[:space:]]*$' file # include white spaces
źródło
spróbuj
pcregrep
zamiast zwykłegogrep
:pcregrep -M "pattern1.*\n.*pattern2" filename
ta
-M
opcja umożliwia dopasowanie w wielu wierszach, więc możesz wyszukiwać nowe wiersze jako\n
.źródło
Dzięki @jarno wiem o opcji -z i dowiedziałem się, że używając GNU grep z opcją -P, dopasowanie do
\n
jest możliwe . :)Przykład:
grep -zoP 'foo\n\K.*'<<<$'foo\nbar'
Wydruki
bar
źródło
grep -zoPnir "dex\n035" ./dir/
Możesz użyć w ten sposób ...
grep -P '^\s$' file
-P
jest używany dla wyrażeń regularnych Perla (rozszerzenie POSIXgrep
).\s
dopasuj białe znaki; jeśli występuje po nim*
, dopasowuje również pusty wiersz.^
dopasowuje początek wiersza.$
dopasowuje koniec linii.źródło
-P
jest rozszerzeniem GNU. Mogę go używać, gdy sytuacja tego wymaga (zwykle lookahead / lookbehind), ale POSIX grep może to zrobić tylko z plikiem[[:space:]]
.-P
. GNU i tak jest dość standardowe. :)brew install grep
zdobyć GNU grep, który jest lepszy pod wieloma względami. apple.stackexchange.com/questions/193288/…Jeśli chodzi o obejście problemu (bez używania nieprzenośnego
-P
), możesz tymczasowo zastąpić znak nowego wiersza innym i zmienić go z powrotem, np:grep -o "_foo_" <(paste -sd_ file) | tr -d '_'
Zasadniczo szuka dokładnego dopasowania,
_foo_
gdzie_
oznacza\n
(więc__
=\n\n
). Nie musisz go tłumaczyć z powrotemtr '_' '\n'
, ponieważ każdy wzór i tak zostałby wydrukowany w nowej linii, więc_
wystarczy usunąć .źródło
<(p paste -sd_ file )
?właśnie znalazłem
grep $'\r'
Używa
$'\r'
do ucieczki w stylu c w Bash.w tym artykule
źródło