Tôi muốn grep trận đấu ngắn nhất và mô hình nên giống như:
<car ... model=BMW ...>
...
...
...
</car>
... Có nghĩa là bất kỳ ký tự nào và đầu vào là nhiều dòng.
Tôi muốn grep trận đấu ngắn nhất và mô hình nên giống như:
<car ... model=BMW ...>
...
...
...
</car>
... Có nghĩa là bất kỳ ký tự nào và đầu vào là nhiều dòng.
Câu trả lời:
Bạn đang tìm kiếm một trận đấu không tham lam (hoặc lười biếng). Để có được một kết quả không tham lam trong các biểu thức thông thường, bạn cần sử dụng công cụ sửa đổi ?
sau bộ định lượng. Ví dụ bạn có thể đổi .*
sang .*?
.
Theo mặc định grep
, không hỗ trợ các sửa đổi không tham lam, nhưng bạn có thể sử dụng grep -P
để sử dụng cú pháp Perl.
.
khớp dòng mới được gọi là chế độ DOTALL hoặc chế độ một dòng ; Ruby là người duy nhất gọi nó là multiline . Trong các hương vị khác, multiline là chế độ cho phép các neo ( ^
và $
) khớp với nhau tại các ranh giới dòng. Ruby không có chế độ tương đương vì trong Ruby chúng luôn hoạt động theo cách đó.
-P
là một cái hoàn toàn mới đối với tôi, tôi đã vui vẻ gồng mình trong nhiều năm và chỉ sử dụng -E
... rất nhiều năm lãng phí! - Lưu ý đến bản thân: Đọc lại các trang Man như một điều thường xuyên (thậm chí nhiều hơn!), Bạn không bao giờ tiêu hóa đủ các công tắc và tùy chọn.
grep
không hỗ trợ -P
, nhưng nếu bạn sử dụng, egrep
bạn có thể sử dụng .*?
mẫu để đạt được kết quả tương tự. egrep -o 'start.*?end' text.html
-P
nhưng -E
sẽ gọi egrep
do đó đề xuất .*?
hoạt động tốt.
Thực tế các .*?
công trình duy nhất trong perl
. Tôi không chắc cú pháp regrec mở rộng grep tương đương sẽ là gì. May mắn thay, bạn có thể sử dụng cú pháp perl với grep vì vậy grep -P
sẽ hoạt động nhưng grep -E
tương tự như egrep
nó sẽ không hoạt động (nó sẽ rất tham lam).
Xem thêm: http://blog.vinceliu.com/2008/02/non-greedy-THER-expression-matching.html
grep -P
không hoạt động trong GNU grep 2.9 - chỉ cần thử nó (nó không bị lỗi, chỉ âm thầm không áp dụng ?
. Intertestly cũng không phải là lớp không, ví dụ:env|grep '[^\=]*\='
grep -P
tùy chọn hoặc pgrep
lệnh nào trong Darwin / OS X 10.8 Mountain Lion, nhưng egrep
hoạt động rất tốt.
pgrep
lệnh trên hộp OS X 10.9 của tôi, nhưng đó là một chương trình hoàn toàn khác với mục đích là "tìm hoặc báo hiệu các quá trình theo tên".
Grep của tôi hoạt động sau khi thử các thứ trong chủ đề này:
echo "hi how are you " | grep -shoP ".*? "
Chỉ cần đảm bảo rằng bạn thêm một khoảng trắng vào mỗi dòng của bạn
(Của tôi là một dòng theo tìm kiếm để nhổ ra từ)
-shoP
ghi nhớ tốt đẹp :)
echo "bbbbb" | grep -shoP 'b.*?b'
là một chút kinh nghiệm học tập. Chỉ có điều làm việc cho tôi về mặt rõ ràng là lười biếng.
grep
Đối với trận đấu không tham lam trong grep
bạn có thể sử dụng một lớp nhân vật bị phủ định. Nói cách khác, cố gắng tránh ký tự đại diện.
Ví dụ: để tìm nạp tất cả các liên kết đến tệp jpeg từ nội dung trang, bạn sẽ sử dụng:
grep -o '"[^" ]\+.jpg"'
Để xử lý nhiều dòng, đặt đầu vào qua xargs
đầu tiên. Để thực hiện, sử dụng ripgrep
.
Câu trả lời ngắn là sử dụng biểu thức chính quy tiếp theo:
(?s)<car .*? model=BMW .*?>.*?</car>
Một (ít) câu trả lời phức tạp hơn là:
(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>
Điều này sẽ làm cho có thể khớp car1 và car2 trong văn bản sau
<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
Xin lỗi tôi trễ 9 năm, nhưng điều này có thể hiệu quả với người xem vào năm 2020.
Vì vậy, giả sử bạn có một dòng như "Hello my name is Jello"
. Bây giờ bạn muốn tìm các từ bắt đầu 'H'
và kết thúc bằng 'o'
, với bất kỳ số lượng ký tự ở giữa. Và chúng tôi không muốn dòng chúng tôi chỉ muốn từ. Vì vậy, chúng ta có thể sử dụng biểu thức:
grep "H[^ ]*o" file
Điều này sẽ trả lại tất cả các từ. Cách thức hoạt động này là: Nó sẽ cho phép tất cả các ký tự thay vì ký tự khoảng trắng ở giữa, theo cách này chúng ta có thể tránh nhiều từ trong cùng một dòng.
Bây giờ bạn có thể thay thế nhân vật không gian bằng bất kỳ nhân vật nào bạn muốn. Giả sử dòng ban đầu là "Hello-my-name-is-Jello"
, sau đó bạn có thể nhận được các từ bằng cách sử dụng biểu thức:
grep "H[^-]*o" file
Tôi biết rằng đó là một chút của một bài viết chết nhưng tôi chỉ nhận thấy rằng điều này làm việc. Nó loại bỏ cả dọn dẹp và dọn dẹp khỏi đầu ra của tôi.
> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20