Để được chính xác
Some text
begin
Some text goes here.
end
Some more text
và tôi muốn trích xuất toàn bộ khối bắt đầu từ "bắt đầu" đến "kết thúc".
với awk chúng ta có thể làm như awk '/begin/,/end/' text
.
Làm thế nào để làm với grep?
Để được chính xác
Some text
begin
Some text goes here.
end
Some more text
và tôi muốn trích xuất toàn bộ khối bắt đầu từ "bắt đầu" đến "kết thúc".
với awk chúng ta có thể làm như awk '/begin/,/end/' text
.
Làm thế nào để làm với grep?
Câu trả lời:
Đã cập nhật ngày 18 tháng 11 năm 2016 (vì hành vi grep đã thay đổi: grep với tham số -P hiện không hỗ trợ ^
và $
neo [trên Ubuntu 16.04 với kernel v: 4.4.0-21-generic]) ( sửa lỗi (không phải) )
$ grep -Pzo "begin(.|\n)*\nend" file
begin
Some text goes here.
end
lưu ý: đối với các lệnh khác, chỉ cần thay thế các neo '^' & '$' bằng neo mới dòng '\n'
____________________________
Với lệnh grep:
grep -Pzo "^begin\$(.|\n)*^end$" file
Nếu bạn muốn không bao gồm các mẫu "bắt đầu" và "kết thúc" trong kết quả, hãy sử dụng grep với hỗ trợ của Lookbehind và Lookahead.
grep -Pzo "(?<=^begin$\n)(.|\n)*(?=\n^end$)" file
Ngoài ra, bạn có thể sử dụng \K
thông báo thay vì khẳng định của Lookbehind.
grep -Pzo "^begin$\n\K(.|\n)*(?=\n^end$)" file
\K
tùy chọn bỏ qua tất cả mọi thứ trước khi khớp mẫu và bỏ qua mẫu chính nó.
\n
được sử dụng để tránh in các dòng trống từ đầu ra.
Hoặc như @AvinashRaj gợi ý có những grep đơn giản dễ dàng như sau:
grep -Pzo "(?s)^begin$.*?^end$" file
grep -Pzo "^begin\$[\s\S]*?^end$" file
(?s)
nói với grep để cho phép dấu chấm khớp với các ký tự dòng mới.
[\s\S]
phù hợp với bất kỳ ký tự nào là khoảng trắng hoặc không phải khoảng trắng.
Và đầu ra của chúng mà không bao gồm "bắt đầu" và "kết thúc" như sau:
grep -Pzo "^begin$\n\K[\s\S]*?(?=\n^end$)" file # or grep -Pzo "(?<=^begin$\n)[\s\S]*?(?=\n^end$)"
grep -Pzo "(?s)(?<=^begin$\n).*?(?=\n^end$)" file
xem thử nghiệm đầy đủ của tất cả các lệnh tại đây ( hết hạn vì hành vi grep với tham số -P bị thay đổi )
^
chỉ điểm bắt đầu của một dòng và $
chỉ điểm cuối của một dòng. những thứ này được thêm vào xung quanh "bắt đầu" và "kết thúc" để khớp với chúng nếu chúng ở một mình trong một dòng.
Trong hai lệnh tôi đã thoát $
vì nó cũng sử dụng cho "Thay thế lệnh" ( $(command)
) cho phép xuất ra lệnh để thay thế tên lệnh.
-o, --only-matching
Print only the matched (non-empty) parts of a matching line,
with each such part on a separate output line.
-P, --perl-regexp
Interpret PATTERN as a Perl compatible regular expression (PCRE)
-z, --null-data
Treat the input as a set of lines, each terminated by a zero byte (the ASCII
NUL character) instead of a newline. Like the -Z or --null option, this option
can be used with commands like sort -z to process arbitrary file names.
grep -Pzo "(?<=begin\n)(.|\n)*(?=\nend)" file
để không in \n
ký tự tồn tại trên dòng bắt đầu.
grep -Pzo "(?s)begin.*?end" file
grep -Pzo "begin[\s\S]*?end" file
grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstützt
Bản dịch của lỗi là một cái gì đó như:grep: a not protected ^ or $ is not supported with -Pz
grep
dường như đã thay đổi.