Dengan asumsi $file
memegang nilai nama file, katakanlah Dr' A.tif
. Dalam pemrograman bash, bagaimana saya bisa lolos dari kutipan tunggal dan karakter khusus lainnya $file
tanpa menghilangkan karakter khusus?
Pembaruan pada 9 Juli 2014
Sebagai permintaan dari @Gilles , cuplikan kode berikut ini yang tidak dapat menangani Dr' A.tif
:
files=$(find /path/ -maxdepth 1 -name "*.[Pp][Dd][Ff]" -o -name "*.[Tt][Ii][Ff]")
echo "${files}" > ${TEMP_FILE}
while read file
do
newfile=$(echo "${file}" | sed 's, ,\\ ,g') ## line 1
done < ${TEMP_FILE}
Setelah saya mencoba jawaban dari @Patrick pada line 1
, sepertinya berhasil untuk saya. Tetapi jika saya memiliki file seperti itu Dr\^s A.tif
, printf
perintah sepertinya tidak membantu, itu menunjukkan kepada saya Dr\^s\ A.tif
. Jika saya mencobanya secara manual di konsol seperti ini:
printf "%q" "Dr\^s A.tif"
Saya akan mendapatkan hasil ini:
Dr\\\^s\ A.tif
Adakah cara menangani ini?
Jawaban:
Anda dapat menggunakan
printf
builtin dengan%q
untuk mencapai ini. Sebagai contoh:Dari dokumentasi bash tentang
printf
:sumber
printf '%s' "foo"
. Anda perlu memahami cara kerja parsing argumen di shell terlebih dahulu. Lihat gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 terjadi sebelum # 6.printf
dan tanpa manipulasi lainIt doesn't have a: ""
printf
. Masalah Anda adalah Anda tidak ingin shell menguraikan string Anda. Untuk melakukan itu, Anda harus meneruskan input Anda ke shell dengan cara di mana ia bahkan tidak mencoba untuk menguraikannya. Salah satu cara untuk melakukan ini adalahread -r -p 'input: ' && printf '%q\n' "$REPLY"
, dan memberikan input saat diminta.printf
. Mungkin Anda harus mengajukan pertanyaan daripada mengkritik solusi yang tidak ada hubungannya dengan masalah Anda.Mencoba:-
atau
atau jika string berisi kutipan ganda: -
Ada tutorial bagus tentang cara melarikan diri dan mengutip di internet. Mulailah dengan yang ini .
sumber
Anda tidak perlu keluar dari nama file apa pun yang Anda tangani dalam skrip. Melarikan diri hanya diperlukan jika Anda ingin meletakkan nama file sebagai literal dalam skrip, atau untuk memberikan beberapa nama file sebagai input stream tunggal ke skrip lain.
Karena Anda mengulang-ulang keluaran
find
, ini adalah salah satu cara paling sederhana (!) Untuk menangani setiap jalur yang mungkin :sumber
cepat dan (sangat) kotor
sumber
Banyak jawaban ini termasuk yang menggunakan suara terbanyak menggunakan
printf "%q"
tidak akan berfungsi dalam semua kasus tanpa manipulasi tambahan. Saya akan menyarankan yang berikut (contoh di bawah):cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn't contain lexemes: "" EOF
sumber