Có hai cấp độ giải thích ở đây: vỏ và sed.
Trong shell, mọi thứ giữa các trích dẫn đơn được diễn giải theo nghĩa đen, ngoại trừ các trích dẫn đơn. Bạn có thể có một trích dẫn duy nhất giữa các trích dẫn đơn bằng cách viết '\''
(trích dẫn đơn, trích dẫn một chữ, trích dẫn đơn).
Sed sử dụng các biểu thức chính quy cơ bản . Trong BRE, để xử lý chúng theo nghĩa đen, các ký tự $.*[\^
cần được trích dẫn bằng cách đặt trước chúng bằng dấu gạch chéo ngược, ngoại trừ bên trong bộ ký tự ( […]
). Chữ cái, chữ số và (){}+?|
không được trích dẫn (bạn có thể thoát khỏi việc trích dẫn một số trong số này trong một số triển khai). Các trình tự \(
, \)
, \n
, và trong một số triển khai \{
, \}
, \+
, \?
, \|
và dấu chéo ngược khác + chữ cái và số có ý nghĩa đặc biệt. Bạn có thể thoát khỏi việc không trích dẫn $^
ở một số vị trí trong một số triển khai.
Hơn nữa, bạn cần một dấu gạch chéo ngược trước /
nếu nó xuất hiện trong biểu thức chính bên ngoài biểu thức ngoặc. Bạn có thể chọn một ký tự thay thế làm dấu phân cách bằng cách viết, ví dụ, s~/dir~/replacement~
hoặc \~/dir~p
; bạn sẽ cần một dấu gạch chéo ngược trước dấu phân cách nếu bạn muốn đưa nó vào BRE. Nếu bạn chọn một ký tự có ý nghĩa đặc biệt trong BRE và bạn muốn bao gồm nó theo nghĩa đen, bạn sẽ cần ba dấu gạch chéo ngược; Tôi không khuyến khích điều này, vì nó có thể hành xử khác đi trong một số triển khai.
Tóm lại, cho sed 's/…/…/'
:
- Viết biểu thức chính giữa các dấu ngoặc đơn.
- Sử dụng
'\''
để kết thúc với một trích dẫn trong regex.
- Đặt dấu gạch chéo ngược trước
$.*/[\]^
và chỉ các ký tự đó (nhưng không nằm trong biểu thức ngoặc). (Về mặt kỹ thuật, bạn không nên đặt dấu gạch chéo ngược trước ]
nhưng tôi không biết về cách triển khai xử lý ]
và \]
khác với biểu thức dấu ngoặc.)
- Trong một biểu thức ngoặc,
-
để được xử lý theo nghĩa đen, hãy đảm bảo rằng nó là đầu tiên hoặc cuối cùng ( [abc-]
hoặc [-abc]
, không [a-bc]
).
- Bên trong một biểu thức khung,
^
để được xử lý theo nghĩa đen, hãy chắc chắn rằng nó không phải là đầu tiên (sử dụng [abc^]
, không phải [^abc]
).
- Để đưa
]
vào danh sách các ký tự khớp với biểu thức ngoặc, hãy đặt nó thành ký tự đầu tiên (hoặc đầu tiên sau ^
cho một tập phủ định): []abc]
hoặc [^]abc]
(không phải [abc]]
cũng không[abc\]]
).
Trong văn bản thay thế:
&
và \
cần được trích dẫn bằng cách đặt trước chúng bằng dấu gạch chéo ngược, cũng như dấu phân cách (thường /
) và dòng mới.
\
theo sau là một chữ số có ý nghĩa đặc biệt. \
theo sau là một chữ cái có một ý nghĩa đặc biệt (các ký tự đặc biệt) trong một số triển khai và \
theo sau là một số ký tự khác có nghĩa \c
hoặc c
tùy thuộc vào việc thực hiện.
- Với các trích dẫn đơn xung quanh đối số (
sed 's/…/…/'
), sử dụng '\''
để đặt một trích dẫn trong văn bản thay thế.
Nếu regex hoặc văn bản thay thế đến từ một biến shell, hãy nhớ rằng
- Regex là một BRE, không phải là một chuỗi chữ.
- Trong regex, một dòng mới cần được thể hiện dưới dạng
\n
(sẽ không bao giờ khớp với trừ khi bạn có sed
mã khác thêm các ký tự dòng mới vào không gian mẫu). Nhưng lưu ý rằng nó sẽ không hoạt động trong biểu thức ngoặc với một số sed
triển khai.
- Trong văn bản thay thế
&
, \
và các dòng mới cần được trích dẫn.
- Dấu phân cách cần được trích dẫn (nhưng không nằm trong biểu thức ngoặc).
- Sử dụng dấu ngoặc kép để nội suy :
sed -e "s/$BRE/$REPL/"
.
function sedPath { path=$((echo $1|sed -r 's/([\$\.\*\/\[\\^])/\\\1/g'|sed 's/[]]/\[]]/g')>&1) } #Escape path for use with sed