sed
API của nó là nguyên thủy - và đây là do thiết kế. Ít nhất, nó vẫn còn nguyên thủy bởi thiết kế - cho dù nó được thiết kế nguyên thủy khi bắt đầu tôi không thể nói. Trong hầu hết các trường hợp, việc viết một sed
tập lệnh mà khi chạy sẽ tạo ra một sed
tập lệnh khác thực sự là một vấn đề đơn giản. sed
thường được áp dụng theo cách này bởi các bộ tiền xử lý macro như m4
và / hoặc make
.
.
Hãy xem xét các tập tin đầu vào sau đây:
cat <<"" >./infile
camel
cat dog camel
dog cat
switch
upper
lower
Nếu chúng ta muốn viết một sed
kịch bản mà sẽ nối từ -case đến đuôi của từng thích hợp từ trong tập tin đầu vào ở trên chỉ nếu nó có thể được tìm thấy trên một dòng trong bối cảnh thích hợp , và chúng tôi mong muốn làm như vậy một cách hiệu quả càng tốt ( như là mục tiêu của chúng tôi, ví dụ, trong một hoạt động biên dịch) thì chúng tôi nên tránh áp dụng /
regrec /
s càng nhiều càng tốt.
Một điều chúng tôi có thể làm là chỉnh sửa trước tệp trên hệ thống của chúng tôi ngay bây giờ và không bao giờ gọi sed
tất cả trong quá trình biên dịch. Nhưng nếu bất kỳ từ nào trong tệp nên hoặc không nên được đưa vào dựa trên cài đặt cục bộ và / hoặc tùy chọn thời gian biên dịch, thì làm như vậy có thể không phải là một lựa chọn thay thế mong muốn.
Một điều khác chúng ta có thể làm là xử lý tệp ngay bây giờ dựa trên biểu thức chính quy. Chúng tôi có thể sản xuất - và bao gồm trong phần tổng hợp của chúng tôi - một sed
tập lệnh có thể áp dụng các chỉnh sửa theo số dòng - thường là một tuyến hiệu quả hơn nhiều trong thời gian dài.
Ví dụ:
n=$(printf '\\\n\t')
grep -En 'camel|upper|lower' <infile |
sed " 1i${n%?}#!/usr/heirloom/bin/posix2001/sed -nf
s/[^:]*/:&$n&!n;&!b&$n&/;s/://2;\$a${n%?}q"'
s/ *cat/!/g;s/ *dog/!/g
s| *\([cul][^ ]*\).*|s/.*/\1-case/p|'
... viết đầu ra dưới dạng một sed
tập lệnh và trông giống như ...
#!/usr/heirloom/bin/posix2001/sed -nf
:1
1!n;1!b1
1s/.*/camel-case/p
:2
2!n;2!b2
2!!s/.*/camel-case/p
:5
5!n;5!b5
5s/.*/upper-case/p
:6
6!n;6!b6
6s/.*/lower-case/p
q
Khi đầu ra đó được lưu vào một tệp văn bản thực thi trên máy của tôi có tên ./bang.sed
và chạy như thế nào ./bang.sed ./infile
, đầu ra là:
camel-case
upper-case
lower-case
Bây giờ bạn có thể hỏi tôi ... Tại sao tôi muốn làm điều đó? Tại sao tôi không chỉ grep
là trận đấu của neo ? Ai sử dụng lạc đà? Và với mỗi câu hỏi tôi chỉ có thể trả lời, tôi không biết ... vì tôi không biết. Trước khi đọc câu hỏi này, tôi chưa bao giờ nhận thấy cá nhân đa! yêu cầu phân tích cú pháp trong thông số kỹ thuật - Tôi nghĩ rằng đó là một cách bắt khá gọn gàng.
Các đa! điều đó ngay lập tức có ý nghĩa với tôi - phần lớn sed
đặc tả được hướng tới các tập lệnh được phân tích cú pháp đơn giản và được tạo rased
. Bạn có thể sẽ tìm thấy các \n
dấu phân cách ewline cần thiết để [wr:bt{]
có ý nghĩa hơn trong bối cảnh đó và nếu bạn giữ ý tưởng đó, bạn có thể hiểu rõ hơn về một số khía cạnh khác của thông số kỹ thuật - (chẳng hạn như :
không chấp nhận địa chỉ và q
từ chối chấp nhận bất kỳ hơn 1) .
Trong ví dụ trên, chúng tôi viết ra một hình thức nhất định của sed
kịch bản mà chỉ có thể từng được đọc một lần. Nếu bạn nhìn chăm chú vào nó, bạn có thể nhận thấy rằng khi sed
đọc tệp chỉnh sửa, nó sẽ chuyển từ khối lệnh này sang khối lệnh tiếp theo - nó không bao giờ tách rời hoặc hoàn thành tập lệnh chỉnh sửa cho đến khi hoàn toàn thông qua tệp chỉnh sửa của nó.
Tôi xem xét rằng đa-! địa chỉ có thể hữu ích hơn trong bối cảnh đó so với một số địa chỉ khác, nhưng, thành thật mà nói, tôi không thể nghĩ đến một trường hợp duy nhất mà tôi có thể sử dụng nó rất tốt - và tôi sed
rất nhiều. Tôi cũng nghĩ rằng đáng chú ý là cả GNU / BSD sed
đều không xử lý được như đã chỉ định - đây có thể không phải là một khía cạnh của thông số kỹ thuật đang có nhiều nhu cầu, và vì vậy nếu một triển khai bỏ qua thì tôi nghi ngờ rất nghiêm trọng lỗi của họ @ box sẽ bị ảnh hưởng kết quả là khủng khiếp
Điều đó nói rằng, việc không xử lý việc này như được chỉ định là một lỗi cho bất kỳ triển khai nào giả vờ tuân thủ và vì vậy tôi nghĩ rằng việc gửi email đến các hộp dev có liên quan được gọi là ở đây và tôi dự định sẽ làm như vậy nếu bạn không làm vậy.
!
hoạt động như một sự chuyển đổi,/pattern/!!
giống như/pattern/
và/pattern/!!!
giống như/pattern/!
. Trên FreeBSD nhiều!
cái giống như một cái duy nhất.