Saya memiliki satu set pengganti sed dalam skrip bash dan saya mendapatkan kesalahan tentang perintah `s 'yang tidak ditakdirkan. Inilah yang terlihat seperti garis sed:
sed -n -e "s/TMPFOO1/$FOO1/" -e "s/TMPFOO2/$FOO2/" -e "s/TMPFOO3/$FOO3/" -e "s/TMPFOO4/$FOO4/" -e "s/TMPFOO5/$FOO5/" /home/foo/template > /home/foo/template/finishedresult
Untuk beberapa alasan, bash tidak suka ini dan saya mendapatkan kesalahan
sed: -e expression #4, char 69: unterminated `s' command
Apa yang kulewatkan di sini? Bagaimana saya bisa meminta SED memasukkan variabel? Bagi saya sepertinya mereka semua dihentikan.
shell-script
text-processing
sed
Mike B
sumber
sumber
Jawaban:
Anda tidak dapat dengan aman menginterpolasi variabel dalam perintah sed, karena penggantian dilakukan oleh shell, bukan oleh sed. Nilai variabel menjadi sintaks sed. Misalnya, dalam
"s/TMPFOO1/$FOO1/"
, jika$FOO1
berisi baris baru, ini akan menyebabkan kesalahan sintaksis seperti yang Anda amati. Jika$FOO1
mengandung a/
, ini mengakhiris
perintah dan dapat menyebabkan kesalahan atau dapat menyebabkan perintah lain dieksekusi (jika apa yang/
terjadi setelahnya adalah sintaks sed yang valid).Meskipun Anda dapat melakukan langkah pertama untuk menggantikan
FOO1
karakter khusus untuk dimasukkan dalam perintah sed, itu jauh lebih mudah untuk menggunakan awk. Awk memiliki gagasan tentang variabel, dan sintaks baris perintah untuk mengatur nilai awal suatu variabel.sumber
-v
kebutuhan untuk mendahului setiap deklarasi variabel.Kemungkinan besar salah satu
$FOO
variabel Anda berisi karakter khusus yang ditafsirkan olehsed
.Saya memiliki versi lain
sed
yang menghasilkan pesan kesalahan lain tetapi di sini adalah contoh dari masalah yang sama:Dalam hal ini
$VAR
berisi karakter yang ditafsirkansed
sebagai garis miring.sumber
Seperti yang disebutkan orang lain di sini, itu tergantung pada konten variabel FOO * Anda. Dalam kasus Anda, menggunakan
sed
adalah pilihan yang salah karena mungkin mengandung beberapa karakter khusus.Lihatlah tautan ini dan lihat fungsinya
gsub_literal
Sejak
gsub_literal
membaca dari stdin dan menulis ke stdout, penggunaannya akan:gsub_literal "$search" "$replace" < /home/foo/template > /home/foo/template/finishedresult
Output sampel:
sumber
Masalahnya telah diatasi untuk saya dengan mencoba backslash tambahan dalam
sed 's/.../.../g'
perintah. Perintah inimemberi saya pesan kesalahan ini
ketika dieksekusi sebagai bagian dari skrip c-shell, dan ia melakukannya hanya dengan versi terbaru
sed
, bukan dengan versi yang lebih lama. (Anehnya, perintah yang sama berfungsi dengan baik ketika diberikan pada baris perintah (dalam shell-tc)).Masalah dengan skrip c-shell telah diatasi dengan mendahului
ä
karakter dengan backslash:sumber