Tại sao những dấu ngoặc nhọn cần thiết trong sed?


8

Tôi muốn thực hiện một tìm kiếm giới hạn trong sed vì vậy tôi đã thử

sed -n '195,210 /add/ p' <file>

Mà đã cho

sed: -e biểu thức # 1, char 9: lệnh không xác định: `/ '

Hoàn toàn là một phỏng đoán, tôi đã thử thêm dấu ngoặc nhọn:

sed -n '195,210{/add/p}' <file>

Và nó đã thành công, nhưng tôi cố gắng hiểu tại sao nó hoạt động với niềng răng được thêm vào.
Tôi nhận được rằng, trong bash, niềng răng có thể phân định một biểu thức (và có thể làm tăng thứ tự thực hiện của nó), nhưng trong trường hợp của sed, những cái niềng răng này đang làm gì?

Thông tin liên quan

$ sed --version
sed (GNU sed) 4.2.2

$ bash --version
GNU bash, version 4.3.11

Câu trả lời:


9

Theo trang tiêu chuẩn POSIX trênsed :

Kịch bản sẽ bao gồm các lệnh chỉnh sửa có dạng sau:

chức năng [ địa chỉ [, địa chỉ ]]

trong đó functionđại diện cho một động từ lệnh một ký tự từ danh sách trong Chỉnh sửa lệnh trong sed , theo sau là bất kỳ đối số áp dụng nào.

Vì vậy, ký tự không trống đầu tiên sau địa chỉ được lấy làm động từ lệnh - trong trường hợp cụ thể của bạn, /do đó, đó là lỗi : char 9: unknown command: '/'.
Niềng răng được tham khảo thêm xuống:

[ 2addr ] { chỉnh sửa lệnh 
chỉnh sửa lệnh
...
}
    Thực hiện một danh sách các lệnh chỉnh sửa `sed` chỉ khi không gian mẫu được chọn. Giáo dục

[ 2addr ] là một chỉ báo cho thấy số lượng địa chỉ cho phép tối đa là hai.

Để làm rõ một điểm thực hiện ở trên, các địa chỉ phần của sed(1)nói:

Sedcác lệnh có thể được cung cấp mà không có địa chỉ, trong trường hợp đó lệnh sẽ được thực thi cho tất cả các dòng đầu vào; với một địa chỉ, trong trường hợp đó, lệnh sẽ chỉ được thực thi cho các dòng đầu vào khớp với địa chỉ đó; hoặc với hai địa chỉ, trong trường hợp đó, lệnh sẽ được thực thi cho tất cả các dòng đầu vào khớp với phạm vi bao gồm của các dòng bắt đầu từ địa chỉ đầu tiên và tiếp tục đến địa chỉ thứ hai. Ba điều cần lưu ý về phạm vi địa chỉ: cú pháp là addr1 , addr2 (nghĩa là các địa chỉ được phân tách bằng dấu phẩy);
        ... (và các công cụ khác không liên quan đến cuộc thảo luận này) ...

Các trang thông tin gnu ( info sed) có một mô tả tương tự {}, dưới "3.4 Các lệnh thường dùng":

{ THÔNG TIN }
    Một nhóm các lệnh có thể được đặt giữa {và các }ký tự. Điều này đặc biệt hữu ích khi bạn muốn một nhóm lệnh được kích hoạt bởi một địa chỉ (hoặc phạm vi địa chỉ) phù hợp.

Nói cách khác, dấu ngoặc nhọn được sử dụng để áp dụng nhiều lệnh tại cùng một địa chỉ hoặc cho các địa chỉ lồng.
Tiêu chuẩn không rõ ràng ở đây 1 nhưng nẹp trái { thực sự là một lệnh bắt đầu một nhóm các lệnh sed khác (nhóm kết thúc bằng một dấu ngoặc phải }).

Và, tại nguy cơ thực sự xảy ra TL; DR , vấn đề là 195, 210/add/là tất cả các địa chỉ . Không có sedlệnh nào có thể được gọi với ba địa chỉ. Vì vậy, cách để làm cho lệnh của bạn hoạt động là gọi {lệnh trên phạm vi địa chỉ 195,210, và sau đó (trong phạm vi đó) gọi plệnh trên địa chỉ /add/.


1:
mặc dù nếu bạn đọc toàn bộ trang, nó được đề cập rằng: Các
động từ lệnh khác với { , a , b , c , i , r , t , w , : , và # có thể được theo sau bởi ...


Cảm ơn vô cùng. Đây là câu trả lời duy nhất giải quyết thực tế là các "nhóm nhiều lệnh" khác không yêu cầu niềng răng, ví dụ như sed -n '195,210s/old/new/p' <file>hoạt động tốt. Liên kết đến tiêu chuẩn POSIX cũng hữu ích.
the_velour_fog

1
@ user4668401 - lưu ý rằng đó 195,210s/old/new/pthực sự là một phạm vi theo sau bởi một lệnh duy nhất : s; trong trường hợp pnày không phải là lệnh, nó là cờ (có nghĩa là in nếu thay thế được thực hiện) xem hướng dẫn sử dụng scú pháp : s/regexp/replacement/flags. Đó là lý do tại sao nó hoạt động mà không cần niềng răng ...
don_crissti

đúng rồi Vì vậy, trong trường hợp của lệnh này : sed -n '195,210{/add/p}' <file>, có 2 lệnh, 1. /add/khớp regex và 2. plệnh in, đó là lý do tại sao {...}khối nẹp là cần thiết?
the_velour_fog

@ user4668401 - vâng, có hai lệnh nhưng lệnh đầu tiên không phải là của bạn /add, nó thực sự {và cho phép bạn lồng một địa chỉ bên trong một lệnh khác. Trả lời chỉnh sửa.
don_crissti

Tôi muốn đề cập rằng nhiều địa chỉ thể có trong vi(hoặc ex) và chúng trông khá giống với sedđịa chỉ.
tự đại diện

3

Theo các tài liệu cho sedcác dấu ngoặc nhọn được sử dụng để nhóm các lệnh lại với nhau. Vì thế

sed -n '195,210{/add/p}' <file>

Đầu tiên được coi là một phạm vi địa chỉ 195,210với một lệnh khối. Lệnh khối sau đó bao gồm các đặc tả địa chỉ /add/với lệnh inp


0

Cú pháp sed đi như

địa chỉ / lệnh.

Vì vậy, 195.210 là địa chỉ đầu tiên bạn khớp, nhưng sau đó bạn muốn thực thi một lệnh mới trong phạm vi đó, cụ thể là khớp "thêm", sau đó in. Do đó, bạn cần nhóm lệnh bổ sung này bằng cách sử dụng dấu ngoặc nhọn.

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.