2009-12-13 21 views
6

Câu hỏi thực sự cơ bản ở đây. Vì vậy, tôi đã nói rằng một dấu chấm. khớp với bất kỳ ký tự nào TRỪ một ngắt dòng. Tôi đang tìm thứ gì đó khớp với bất kỳ ký tự nào, kể cả ngắt dòng.Có một ký tự đại diện thực sự phổ biến ở Grep không?

Tất cả những gì tôi muốn làm là chụp tất cả văn bản trong trang web giữa hai chuỗi cụ thể, tước đầu trang và chân trang. Một cái gì đó giống như HEADER TEXT (. +) FOOTER TEXT và sau đó trích xuất những gì trong dấu ngoặc đơn, nhưng tôi không thể tìm cách để bao gồm tất cả các ngắt dòng văn bản AND giữa đầu trang và chân trang, điều này có ý nghĩa không? Cảm ơn trước!

Trả lời

7

Khi tôi cần phải phù hợp nhiều ký tự, bao gồm ngắt dòng, tôi làm:

[\s\S]*? 

Note Tôi đang sử dụng một mô hình phi tham lam

+2

Xin cảm ơn các bạn! Thật là một trang hữu ích, thân thiện. Tôi quên đề cập đến rằng tôi đã sử dụng grep tìm kiếm trong BBEdit, điều này hoạt động tuyệt vời. Bạn tất cả đá! –

3

Bạn có thể làm điều đó với Perl:

$ perl -ne 'print if /HEADER TEXT/ .. /FOOTER TEXT/' file.html 

Để in chỉ văn bản giữa các delimiters, sử dụng

$ perl -000 -lne 'print $1 while /HEADER TEXT(.+?)FOOTER TEXT/sg' file.html 

Việc chuyển đổi /s làm cho sự biểu hiện khớp thường xuyên đối xử với toàn bộ chuỗi như một s dòng ingle, có nghĩa là dấu chấm khớp với dòng mới và /g có nghĩa là khớp nhiều lần nhất có thể.

Các ví dụ ở trên giả sử bạn đang quay vòng trên các tệp HTML trên đĩa cục bộ. Nếu bạn cần phải lấy họ đầu tiên, sử dụng get từ LWP::Simple:

$ perl -MLWP::Simple -le '$_ = get "http://stackoverflow.com"; 
          print $1 while m!<head>(.+?)</head>!sg' 

Xin lưu ý rằng phân tích cú pháp HTML với biểu thức thông thường như trên không hoạt động trong trường hợp tổng quát! Nếu bạn đang làm việc trên một máy quét nhanh và bẩn, tốt, nhưng đối với một ứng dụng cần phải mạnh mẽ hơn, hãy sử dụng một trình phân tích cú pháp thực.

1

Như được chỉ định ở nơi khác, grep sẽ hoạt động cho các công cụ đơn dòng.

Đối với nhiều dòng (trong ruby ​​với regexp :: MULTILINE, hoặc trong python, awk, sed, bất cứ điều gì), "\ s" nên cũng chụp ngắt dòng, vì vậy

HEADER TEXT(.*\s*)FOOTER TEXT 

có thể làm việc .. .

+0

Bạn sẽ phải đọc tệp ở chế độ quét nhiều dòng vào bộ nhớ để làm việc. –

+0

Cảm ơn, tôi đã thêm vào cách bạn làm điều đó trong Ruby. IIRC, đó là/g trong tiếng Anh, phải không? – phtrivier

2

các trang người đàn ông của grep nói:

grep, egrep, fgrep, rgrep - dòng in phù hợp với một mô hình

grep không được thực hiện để khớp nhiều hơn một dòng. Bạn nên cố gắng giải quyết tác vụ này với perl hoặc awk.

3

Theo định nghĩa, grep sẽ tìm các đường phù hợp; nó đọc một dòng, xem liệu nó có khớp hay không, và in dòng.

Một cách tốt để làm những gì bạn muốn là với sed:

sed -n '/HEADER TEXT/,/FOOTER TEXT/p' "[email protected]" 

này in từ dòng đầu tiên phù hợp 'HEADER TEXT' vào dòng đầu tiên phù hợp 'FOOTER TEXT', và sau đó lặp; '-n' dừng hoạt động 'in từng dòng' mặc định. Điều này sẽ không hoạt động tốt nếu văn bản đầu trang và chân trang xuất hiện trên cùng một dòng.

Để làm những gì bạn muốn, tôi có thể sử dụng perl (nhưng bạn có thể sử dụng Python nếu bạn thích). Tôi sẽ xem xét slurping toàn bộ tập tin, và sau đó sử dụng một regex đủ điều kiện phù hợp để tìm các phần phù hợp của tập tin. Tuy nhiên, Perl một lớp lót được đưa ra bởi '@gbacon' là một chuyển ngữ gần như chính xác vào Perl của kịch bản 'sed' ở trên và là neater hơn slurping.

0

đây là một cách để làm điều đó với gawk, nếu bạn có nó

awk -vRS="FOOTER" '/HEADER/{gsub(/.*HEADER/,"");print}' file 
2

Vì đây được gắn thẻ với 'BBEdit' và BBEdit hỗ trợ Perl-Style Modifiers Pattern bạn có thể cho phép các dấu chấm để phù hợp với linebreaks với công tắc (? s)

0.123.

(? S).

sẽ khớp với bất kỳ ký tự nào. Và có, (? S). + sẽ khớp với toàn bộ văn bản.

Các vấn đề liên quan