Untuk menghindari variabel yang akan digunakan di sisi kiri dan kanan dari sperintah di sed( di sini $lhsdan $rhsmasing - masing), Anda harus melakukan:
escaped_lhs=$(printf '%s\n' "$lhs" | sed 's:[][\/.^$*]:\\&:g')
escaped_rhs=$(printf '%s\n' "$rhs" | sed 's:[\/&]:\\&:g;$!s/$/\\/')
sed "s/$escaped_lhs/$escaped_rhs/"
Catatan yang $lhstidak dapat berisi karakter baris baru.
Yaitu, pada LHS, lepas dari semua operator regexp ( ][.^$*), karakter yang melarikan diri itu sendiri ( \), dan pemisah ( /).
Pada RHS, Anda hanya perlu melarikan diri &, pemisah, garis miring terbalik dan karakter baris baru (yang Anda lakukan dengan memasukkan garis miring terbalik di akhir setiap baris kecuali yang terakhir ( $!s/$/\\/)).
Itu mengasumsikan Anda menggunakan /sebagai pemisah dalam sed sperintah Anda dan bahwa Anda tidak mengaktifkan Extended REs dengan -r(GNU sed/ ssed/ ast/ busybox sed) atau -E(BSDs,, astGNU baru-baru ini, busybox terbaru) atau PCREs dengan -R( ssed) atau Augmented REs dengan -A/ -X( ast) yang semua memiliki operator RE ekstra.
Beberapa aturan dasar saat berurusan dengan data sewenang-wenang:
- Jangan gunakan
echo
- kutip variabel Anda
- pertimbangkan dampak dari locale (terutama set karakternya: penting bahwa perintah escaping
sed dijalankan di locale yang sama dengan sedperintah yang menggunakan string escaped (dan dengan sedperintah yang sama ) misalnya)
- jangan lupa tentang karakter baris baru (di sini Anda mungkin ingin memeriksa apakah
$lhsberisi dan mengambil tindakan).
Pilihan lain adalah menggunakan perlalih-alih seddan meneruskan string di lingkungan dan menggunakan operator \Q/ \E perlregexp untuk mengambil string secara harfiah:
A="$lhs" B="$rhs" perl -pe 's/\Q$ENV{A}\E/$ENV{B}/g'
perl(secara default) tidak akan terpengaruh oleh set karakter lokal karena, di atas, ia hanya menganggap string sebagai array byte tanpa peduli tentang karakter apa (jika ada) yang mungkin mereka wakili untuk pengguna. Dengan sed, Anda dapat mencapai hal yang sama dengan memperbaiki lokal ke Cdengan LC_ALL=Cuntuk semua sedperintah (meskipun itu juga akan mempengaruhi bahasa pesan kesalahan, jika ada).