Ba sed
lệnh khác nhau :
sed '$!N;s/"[^"]*"\n<[^>]*>/other characters /;P;D'
sed -e :n -e '$!N;s/"[^"]*"\n<[^>]*>/other characters /;tn'
sed -e :n -e '$!N;/"$/{$!bn' -e '};s/"[^"]*"\n<[^>]*>/other characters /g'
Cả ba đều xây dựng trên s///
lệnh ubstlation cơ bản :
s/"[^"]*"\n<[^>]*>/other characters /
Tất cả họ cũng cố gắng cẩn thận trong việc xử lý dòng cuối cùng, vì sed
s có xu hướng khác nhau về đầu ra của họ trong các trường hợp cạnh. Đây là ý nghĩa của $!
một địa chỉ phù hợp với mọi dòng !
không phải là $
cuối cùng.
Tất cả chúng cũng sử dụng N
lệnh ext để nối dòng đầu vào tiếp theo vào không gian mẫu theo \n
ký tự ewline. Bất cứ ai đã làm sed
việc trong một thời gian sẽ học được cách dựa vào \n
nhân vật ewline - bởi vì cách duy nhất để có được một người rõ ràng là đặt nó ở đó.
Cả ba đều thực hiện một số nỗ lực để đọc càng ít đầu vào càng tốt trước khi thực hiện hành động - sed
hành động ngay khi có thể và không cần đọc trong toàn bộ tệp đầu vào trước khi thực hiện.
Mặc dù họ làm tất cả N
, cả ba đều khác nhau về phương pháp đệ quy.
Lệnh đầu tiên
Lệnh đầu tiên sử dụng một N;P;D
vòng lặp rất đơn giản . Ba lệnh này được tích hợp sẵn cho bất kỳ tương thích POSIX nào sed
và chúng bổ sung cho nhau một cách độc đáo.
N
- như đã đề cập, nối thêm N
dòng đầu vào ext vào không gian mẫu theo \n
dấu phân cách ewline được chèn .
P
- thích p
; nó P
gợi ý không gian mẫu - nhưng chỉ tối đa đến \n
ký tự ewline xuất hiện đầu tiên . Và do đó, đưa ra đầu vào / lệnh sau:
printf %s\\n one two | sed '$!N;P;d'
sed
P
gợi ý chỉ một . Tuy nhiên, với ...
D
- thích d
; nó D
xóa bỏ không gian mẫu và bắt đầu một chu trình dòng khác. Không giống như d
, D
chỉ xóa tối đa \n
ewline xuất hiện đầu tiên trong không gian mẫu. Nếu có nhiều hơn trong không gian mẫu theo \n
ký tự ewline, hãy sed
bắt đầu chu trình dòng tiếp theo với những gì còn lại. Nếu d
ví dụ trước được thay thế bằng a D
, ví dụ, sed
sẽ P
rint cả một và hai .
Lệnh này chỉ đệ quy cho các dòng không khớp với s///
tuyên bố ubstlation. Bởi vì s///
ubstlation loại bỏ \n
ewline được thêm vào N
, không bao giờ có bất cứ điều gì còn lại khi sed
D
xóa bỏ không gian mẫu.
Các thử nghiệm có thể được thực hiện để áp dụng P
và / hoặc D
chọn lọc, nhưng có các lệnh khác phù hợp hơn với chiến lược đó. Bởi vì đệ quy được triển khai để xử lý các dòng liên tiếp chỉ khớp với một phần của quy tắc thay thế, các chuỗi liên tiếp khớp với cả hai đầu của s///
ubstlation không hoạt động tốt.:
Cho đầu vào này:
first "line"
<second>"line"
<second>"line"
<second>line and so on
... nó in ...
first other characters "line"
<second>other characters line and so on
Nó, tuy nhiên, xử lý
first "line"
second "line"
<second>line
...bình thường.
Bộ chỉ huy thứ hai
Lệnh này rất giống với lệnh thứ ba. Cả hai đều sử dụng nhãn :b
ranch / t
est (như được thể hiện trong câu trả lời của Joeseph R. ở đây ) và tái diễn lại với điều kiện nhất định.
-e :n -e
- sed
tập lệnh di động sẽ phân định một :
định nghĩa nhãn bằng \n
ewline hoặc -e
câu lệnh xecut nội tuyến mới .
:n
- định nghĩa một nhãn có tên n
. Điều này có thể được trả lại cho bất cứ lúc nào với một trong hai bn
hoặc tn
.
tn
- t
lệnh est trở về nhãn đã chỉ định (hoặc, nếu không được cung cấp, thoát khỏi tập lệnh cho chu kỳ dòng hiện tại) nếu bất kỳ s///
ubstlation nào kể từ khi nhãn được xác định hoặc do lần cuối được gọi là t
ests thành công.
Trong lệnh này, đệ quy xảy ra cho các dòng khớp. Nếu sed
thay thế thành công mẫu bằng các ký tự khác , sed
quay lại :n
nhãn và thử lại. Nếu một s///
ubstlation không được thực hiện tự động sed
in không gian mẫu và bắt đầu chu kỳ dòng tiếp theo.
Điều này có xu hướng xử lý các chuỗi liên tiếp tốt hơn. Trường hợp cuối cùng thất bại, bản in này:
first other characters other characters other characters line and so on
Bộ ba
Như đã đề cập, logic ở đây rất giống với cuối cùng, nhưng thử nghiệm rõ ràng hơn.
/"$/bn
- đây là sed
bài kiểm tra. Vì b
lệnh ranch là một chức năng của địa chỉ này, nên sed
sẽ chỉ b
quay lại :n
sau khi một \n
ewline được nối thêm và không gian mẫu vẫn kết thúc bằng một "
trích dẫn kép.
Có rất ít được thực hiện giữa N
và b
càng tốt - theo cách này sed
có thể nhanh chóng thu thập chính xác càng nhiều đầu vào càng cần thiết để đảm bảo rằng dòng sau không thể phù hợp với quy tắc của bạn. Các s///
ubstlation khác nhau ở đây ở chỗ nó sử dụng g
cờ thùy - và do đó, nó sẽ thực hiện tất cả các thay thế cần thiết cùng một lúc. Cho đầu vào giống hệt lệnh này đầu ra giống hệt đến cuối cùng.
\n
tuyên bố ewline bạn thực hiện là lý do tại sao tôi hỏi. mọi người hiếm khi hỏi liệu họ có thể làms//\n/
như bạn có thể với GNU hay khôngsed
, mặc dù hầu hết những người khácsed
sẽ từ chối lối thoát đó ở phía bên tay phải. Tuy nhiên,\n
lối thoát sẽ hoạt động ở bên trái trong bất kỳ POSIX nàosed
và bạn có thể dịch chúng một cách hợp lý như thếy/c/\n/
mặc dù nó sẽ có tác dụng tương tựs/c/\n/g
và vì vậy không phải lúc nào cũng hữu ích.