In các dòng giữa (và loại trừ) hai mẫu


13

Tôi sẽ gửi biểu mẫu bằng cURL, trong đó một số nội dung đến từ tệp khác, được chọn bằng cách sử dụng sed

Nếu param1mẫu khớp dòng từ tệp khác sử dụng sed, lệnh bên dưới sẽ hoạt động tốt:

curl -d param1="$(sed -n '/matchpattern/p' file.txt)" -d param2=value2 http://example.com/submit

Bây giờ, đi đến vấn đề. Tôi muốn chỉ hiển thị văn bản giữa 2 mẫu phù hợp, ngoại trừ mẫu phù hợp.

Hãy nói file.txtcó chứa:

Bla bla bla
firstmatch
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.
secondmatch
The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.

Hiện tại, rất nhiều lệnh "giữa 2 mẫu phù hợp" sedsẽ không xóa firstmatchsecondmatch.

Tôi muốn kết quả trở thành:

It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.

Câu trả lời:


15

Đây là một cách bạn có thể làm điều đó:

sed '1,/firstmatch/d;/secondmatch/,$d' 

Giải thích: Từ dòng đầu tiên đến dòng khớp firstmatch , xóa. Từ dòng khớp thứ hai đến dòng cuối cùng, xóa.



5

sedGiải pháp khác sẽ thất bại nếu firstmatchxảy ra trên dòng 1 .

Giữ cho nó đơn giản, sử dụng một phạm vi duy nhất và 2 regex trống :
hoặc in mọi thứ trong phạm vi đó ngoại trừ kết thúc phạm vi (tự động in bị tắt) 3 :

sed -n '/firstmatch/,/secondmatch/{//!p;}' infile

hoặc, ngắn hơn, xóa mọi thứ không nằm trong phạm vi đó và cũng xóa phạm vi kết thúc:

sed '/firstmatch/,/secondmatch/!d;//d' infile


1: Lý do là nếu địa chỉ thứ hai là regrec, thì việc kiểm tra kết thúc khớp sẽ bắt đầu bằng dòng theo dòng khớp với địa chỉ đầu tiên .
Do đó, /firstmatch/không bao giờ được đánh giá cho dòng đầu tiên của đầu vào, sedsẽ chỉ xóa nó vì nó khớp với số dòng trong 1,/RE/và chuyển sang dòng thứ 2 nơi nó kiểm tra xem dòng có khớp không/firstpattern/

2: Khi REGEX trống (nghĩa là //) sedhoạt động như thể REGEX cuối cùng được sử dụng trong lệnh cuối cùng được áp dụng (dưới dạng địa chỉ hoặc là một phần của lệnh thay thế) đã được chỉ định.

3: ;}cú pháp dành cho sedviệc triển khai hiện đại ; với những cái cũ hơn sử dụng một dòng mới thay vì dấu chấm phẩy hoặc các biểu thức riêng biệt, vdsed -n -e '/firstmatch/,/secondmatch/{//!p' -e '}' infile


Bạn có thể giải thích những gì //đang làm (bên trong {…})?
G-Man nói 'Phục hồi Monica'

Cảm ơn, nhưng bạn rơi vào bẫy của tôi. Tôi biết điều đó //có nghĩa là biểu thức chính quy cuối cùng được sử dụng; từ tất cả những gì tôi đã đọc, nên như vậy /secondmatch/. Tôi đã xác minh thông qua kiểm tra rằng lệnh của bạn hoạt động và vì vậy tôi đã kết luận rằng nó đang hoạt động như /firstmatch|secondmatch/(mà bạn đã xác nhận), nhưng tôi không thể tìm thấy bất kỳ tài liệu nào (ngay cả tài liệu POSIX mà bạn đã liên kết đến hoặc GNU hướng dẫn sử dụng sed ) mô tả hành vi này. Tiết (Cont'd)
G-Man nói 'Tái lập lại'

(Tiếp theo) Thử nghiệm giải trí hấp dẫn: (I) Trong sed: (1) Nếu tôi làm /first/,4, thì //hành động như thế /first/. (2) Nếu tôi làm như vậy 2,/second/, thì //sẽ có một lỗi không có biểu thức chính quy trước đó. (Tôi thấy đây là một sự thất bại trắng trợn khi tuân theo hành vi được chỉ định.) (3) Thêm --posixkhông thay đổi một trong hai điều trên. (II) Trong các chương trình khác: (4) Trong vi, sau đó /first/,/second/, //các hành động như /second/(và các hình thức khác cũng là triển khai hợp lý của quy tắc tài liệu). Tiết (Cont'd)
G-Man nói 'Tái lập lại'

(Tiếp theo), (5)  awkdường như không có khái niệm gì về việc RE sử dụng RE cuối cùng; //đề cập đến phi ký tự trước hoặc sau bất kỳ ký tự nào. (Tôi mời bạn dùng thử echo -- | awk '{ gsub(//, "cha"); print }'.)
G-Man nói 'Tái lập lại Monica'

Vì vậy, bạn đã đọc tiếng REGEX cuối cùng được sử dụng trong lệnh cuối cùng là vì tên REGEX cuối cùng được sử dụng trong lệnh cuối cùng và do đó, bạn (đoán) chính xác rằng nó có nghĩa /first|second/. Bạn thật may mắn. Tôi đề cập đến các chương trình khác để chứng minh rằng đây không phải là một quy ước regex toàn hệ thống. Bất cứ ai thêm nó vào sedđều không bận tâm để thêm nó vào vim, nơi mà nó sẽ có ý nghĩa nhiều như vậy. :-)
G-Man nói 'Tái lập lại'
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.