Làm thế nào để đưa ra một mẫu cho dòng mới trong grep?


95

Làm thế nào để đưa ra một mẫu cho dòng mới trong grep? Dòng mới ở đầu, dòng mới ở cuối. Không phải là cách biểu thức chính quy. Một cái gì đó giống như \ n.


6
Không rõ bạn muốn gì. new line at the beginninglà một dòng trống và new line at endáp dụng cho mọi dòng trong tệp. Bạn có thể đăng một ví dụ?
PP

2
Trên thực tế, bạn chỉ có thể sử dụng $. Nó hơi hạn chế, nhưng có thể sử dụng được trong những trường hợp đơn giản.
Krzysztof Jabłoński

Câu trả lời:


84

grep các mẫu được khớp với các dòng riêng lẻ nên không có cách nào để một mẫu khớp với một dòng mới được tìm thấy trong đầu vào.

Tuy nhiên, bạn có thể tìm thấy các dòng trống như thế này:

grep '^$' file
grep '^[[:space:]]*$' file # include white spaces 

Ít nhất GNU grep có tùy chọn -z làm cho các dòng ngắt grep bằng ký tự rỗng. Tuy nhiên, nó dường như không hỗ trợ dòng mới hoặc \ n trong mẫu để khớp với dòng mới, hãy xem báo cáo lỗi .
jarno

1
@jarno Nó hỗ trợ \ n trong các mẫu có cờ -P
rubystallion

92

thử pcregrepthay vì thông thường grep:

pcregrep -M "pattern1.*\n.*pattern2" filename

các -Mtùy chọn cho phép nó để phù hợp trên nhiều dòng, vì vậy bạn có thể tìm kiếm dòng mới như \n.


22

Bạn có thể sử dụng cách này ...

grep -P '^\s$' file
  • -Pđược sử dụng cho các biểu thức chính quy Perl (một phần mở rộng cho POSIX grep).
  • \skhớp các ký tự khoảng trắng; nếu theo sau *, nó cũng khớp với một dòng trống.
  • ^khớp với đầu dòng. $khớp với cuối dòng.

2
-Plà một phần mở rộng GNU. Tôi ổn khi sử dụng nó khi tình huống yêu cầu nó (thường là lookahead / lookbehind), nhưng POSIX grep có thể làm điều này chỉ với tệp [[:space:]].
jordanm

1
Các trang grep của FWIW, Solaris 'và BSD (không kiểm tra những người khác) đều có một đoạn cho -P. GNU dù sao cũng khá chuẩn. :)
K3 --- rnc

1
Từ trang hướng dẫn: [-P] Tùy chọn này không được hỗ trợ trong FreeBSD.
Marián Černý

Cũng không có [-P] cho MacOsX: grep [-abcdDEFGHhIiJLlmnOopqRSsUVvwxZ] [-A num] [-B num] [-C [num]] [-e pattern] [-f file] [--binary-files = value] [--color [= when]] [--colour [= when]] [--context [= num]] [--label] [--line-buffered] [--null] [pattern] [tệp. ..]
Niccolò

@ Niccolò Bạn sẽ muốn brew install grepnhận GNU grep, tính năng này vượt trội hơn theo một số cách. apple.stackexchange.com/questions/193288/…
bầy đàn vào

19

Nhờ @jarno, tôi biết về tùy chọn -z và tôi phát hiện ra rằng khi sử dụng GNU grep với tùy chọn -P, việc so khớp với \nlà có thể . :)

Thí dụ:

grep -zoP 'foo\n\K.*'<<<$'foo\nbar'

Bản in bar


1
Tuyệt vời, lưu ý rằng tôi không nhận được thông báo về "@jarno" trong câu trả lời.
jarno

3
Điều đó thật tuyệt! Cảm ơn bạn rất nhiều vì đã chia sẻ!
Alicia Tang

6

Đối với cách giải quyết khác (không sử dụng tính năng không di động -P), bạn có thể tạm thời thay thế một ký tự dòng mới bằng ký tự khác và thay đổi lại nó, ví dụ:

grep -o "_foo_" <(paste -sd_ file) | tr -d '_'

Về cơ bản nó đang tìm kiếm kết hợp chính xác _foo_nơi _phương tiện \n(như vậy __= \n\n). Bạn không cần phải dịch ngược lại tr '_' '\n', vì dù sao thì mỗi mẫu sẽ được in ở dòng mới, vì vậy chỉ cần loại bỏ _là đủ.


thứ lỗi cho sự thiếu hiểu biết của tôi, nhưng việc sử dụng quy trình thay thế chưa tương thích với posix NON khác, do đó có tính năng không di động? trong posix shell tôi không thể làm gì <(p paste -sd_ file )?
humanityANDpeace

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.