quyến rũ và những người khác không làm việc cùng nhau


7

Đưa ra điều này:

echo AAA | sed -r 's/A/echo B/ge'

Tôi nhận được điều này:

Becho Becho B

Tôi đã nghĩ rằng tôi sẽ nhận được "BBB". Đây là phiên bản GNU sed 4.2.1. Điều gì đang xảy ra và làm cách nào tôi có thể sử dụng cờ thực thi và có nhiều thay thế có thể xảy ra trên một dòng (từ shell chứ không phải từ perl et al)?

Câu trả lời:


8

Các cờ hoạt động cùng nhau theo cách ngược lại với những gì bạn mong đợi. Các tài liệu của /e , đối với các bản ghi:

Lệnh này cho phép một đầu vào đường ống từ lệnh shell vào không gian mẫu. Nếu thay thế được thực hiện, lệnh được tìm thấy trong không gian mẫu được thực thi và không gian mẫu được thay thế bằng đầu ra của nó. Một dòng mới kéo dài bị đàn áp; kết quả không được xác định nếu lệnh được thực thi có chứa ký tự nul. Đây là một phần mở rộng GNU sed.

Đó là một chút quanh co viết. Điều đó có nghĩa là, sau khi hoàn thành một s///lệnh cho dòng này, nếu có thay đổi, dòng (mới) được thực thi như một lệnh và đầu ra của nó được sử dụng làm thay thế cho dòng này.

Vì vậy, đối với lệnh đã cho của bạn:

echo AAA | sed -r 's/A/echo B/ge'

nó đầu tiên thay thế từng Aecho B, và sau đó thực hiện kết quả như một lệnh. Nó có (nói đại khái) có tác dụng tương tự như:

echo AAA | sed -r 's/A/echo B/g' | sh

GNU sedkhông hỗ trợ trực tiếp chế độ bạn muốn, mặc dù bạn có thể giả mạo nó với một tập lệnh phức tạp hơn nếu muốn. Ngoài ra, công cụ /esửa đổi của Perl cho slệnh của nó có hành vi bạn đang tìm kiếm, nhưng thay vào đó với các biểu thức Perl.


Aha - thực thi lệnh mà nó tìm thấy trong không gian mẫu sau khi xử lý toàn bộ dòng! OK đó là một số ý nghĩa. Mặc dù Perl làm những gì tôi muốn với hai lá cờ được đặt. Cám ơn.
spinkus

4

Bạn đang nhận được nhiều sự thay thế, nhưng bạn không nhận được nhiều lần thực hiện. Mẫu được thực hiện khi tất cả các thay thế đã được thực hiện.

Không có ecờ kết quả của

echo AAA | sed -r 's/A/echo B/g'

echo Becho Becho B

Vì vậy, đó là dòng lệnh đó là thực hiện nếu bạn làm bao gồm các elá cờ, mà là tương đương với

echo 'Becho Becho B'

2

Để nhận 'BBB' từ 'AAA' bằng cách sử dụng lệnh 's' của GNU sed với cờ 'e', ​​người ta có thể làm điều này:

echo AAA | sed -re 's/A/echo -n B;/ge'

'AAA' được thay thế bằng 'echo -n B; echo -n B; echo -n B; ', mà cuối cùng khi được thực thi sẽ dẫn đến 3 lệnh echo chạy liên tục, một lệnh cho mỗi trận đấu toàn cầu. '-N' bỏ qua các ký tự dòng từ đầu ra của tiếng vang, làm cho 'B' kết thúc trên một dòng (nhưng sed sẽ tự thêm một nguồn cấp dữ liệu khi cuối cùng in không gian mẫu).


1

Một vài thứ:

(1) Trường hợp sử dụng chính xác mà bạn mô tả có thể được xử lý chỉ với

echo AAA | sed 's/A/B/g'

(2) Để thực hiện, nếu đó là cụ thể những gì bạn muốn (đối với việc sử dụng nâng cao hơn là chỉ lặp lại), bạn có thể sử dụng ecờ làm bước cuối cùng:

echo AAA | sed -r 's/A/B/g;s/(.*)/echo \1/e'

(3) Nếu bạn muốn chỉ thực hiện lệnh nếu lệnh thay thế FIRST thay thế một cái gì đó, hãy sử dụng một nhánh:

echo AAA | sed -r 's/A/B/g;te;b;:e;s/(.*)/echo \1/e'

Chúng chỉ hoạt động trong GNU sednhư được viết ở trên. BSD sed(ít nhất là phiên bản tôi có) không hỗ trợ -rtùy chọn và yêu cầu một chuỗi kết thúc để theo tên chi nhánh. (Bạn có thể làm việc xung quanh điểm cuối cùng này bằng cách thêm nhiều -etùy chọn với các đối số.)

Lưu ý rằng với đầu vào đã cho (AAA), ba lớp lót này đều giống nhau về mặt chức năng. Nhưng nếu echolệnh được thay đổi thành thứ khác hoặc nếu -ntùy chọn được chuyển sang sed, bạn sẽ thấy sự khác biệt.

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.