Bagaimana saya bisa menghindari tanda kutip ganda di dalam string ganda di Bash?
Misalnya, dalam skrip shell saya
#!/bin/bash
dbload="load data local infile \"'gfpoint.csv'\" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY \"'\n'\" IGNORE 1 LINES"
Saya tidak bisa mendapatkan ENCLOSED BY '\"'
dengan kutipan ganda untuk melarikan diri dengan benar. Saya tidak dapat menggunakan tanda kutip tunggal untuk variabel saya, karena saya ingin menggunakan variabel $dbtable
.
$dbtable
, ada risiko. Ini akan sangat tidak biasa, karena pengguna akhir biasanya tidak SSH ke mesin untuk memuat data mereka.Jawaban:
Gunakan garis miring terbalik:
sumber
x=ls; if [ -f "$(which "\""$x"\"")" ]; then echo exists; else echo broken; fi;
memberi rusak sementara... [ -f "$(which $x)" ]; ...
atau... [ -f $(which "$x") ]; ...
bekerja dengan baik. Masalah akan muncul ketika salah satu$x
atau hasil$(which "$x")
memberikan apa pun dengan spasi atau karakter khusus lainnya. Penanganan masalah menggunakan variabel untuk mempertahankan hasilwhich
, tetapi apakah bash benar-benar tidak mampu menghindari penawaran atau apakah saya melakukan sesuatu yang salah?grep -oh "\"\""$counter"\""\w*"
sebagai bagian dari sintaks bash di mana$counter
adalah variabel. itu tidak suka pikiranContoh sederhana untuk keluar dari kutipan di shell:
Ini dilakukan dengan menyelesaikan yang sudah dibuka (
'
), menempatkan yang lolos (\'
), dan kemudian membuka yang lain ('
).Kalau tidak:
Ini dilakukan dengan menyelesaikan yang sudah dibuka satu (
'
), menempatkan kutipan di kutipan lain ("'"
), dan kemudian membuka yang lain ('
).Lebih banyak contoh: Melarikan diri dari tanda kutip tunggal di dalam string kutipan tunggal
sumber
echo "abc\"abc"
cukup untuk menghasilkanabc"abc
seperti pada jawaban Peter.Saya tidak tahu mengapa masalah lama ini muncul hari ini di daftar yang ditandai Bash, tetapi untuk berjaga-jaga bagi para peneliti di masa depan, ingatlah bahwa Anda dapat menghindari melarikan diri dengan menggunakan kode ASCII dari karakter yang harus Anda gema.
Contoh:
\x22
adalah kode ASCII (dalam hex) untuk tanda kutip ganda dan\x27
untuk tanda kutip tunggal. Demikian pula Anda dapat menggemakan karakter apa pun.Saya kira jika kita mencoba untuk menggemakan string di atas dengan backslash, kita akan membutuhkan dua baris berantakan backslashed ... :)
Untuk penugasan variabel, ini setara dengan:
Jika variabel sudah ditetapkan oleh program lain, Anda masih bisa menerapkan tanda kutip ganda / tunggal dengan sed atau alat serupa.
Contoh:
sumber
echo 'export PS1='\[\033[00;31m\]${?##0}$([ $? -ne 0 ] && echo \x22 \x22)\[\033[00;32m\]\u\[\033[00m\]@\[\033[00;36m\]\h\[\033[00m\][\[\033[01;33m\]\d \t\[\033[00m\]] \[\033[01;34m\]\w\n\[\033[00m\]$( [ ${EUID} -ne 0 ] && echo \x22$\x22 || echo \x22#\x22 ) '' >> ~/.profile
Bash memungkinkan Anda untuk menempatkan string secara berdekatan, dan mereka hanya akan terpaku bersama.
Jadi ini:
menghasilkan
Caranya adalah dengan mengganti antara string tunggal dan ganda seperti yang diminta. Sayangnya, dengan cepat menjadi sangat berantakan. Sebagai contoh:
menghasilkan
Dalam contoh Anda, saya akan melakukannya seperti ini:
yang menghasilkan output berikut:
Sulit untuk melihat apa yang terjadi di sini, tetapi saya dapat menjelaskannya menggunakan kutipan Unicode. Berikut ini tidak akan berfungsi dalam bash - itu hanya untuk ilustrasi:
dbload=
'load data local infile "
' “'gfpoint.csv'
'" into
'table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '
'"
'' LINES
'TERMINATED BY "
''\n'
'" IGNORE 1 LINES
' ' ' ' ' ' ' ' ' ' 'Kutipan seperti "''" di atas akan ditafsirkan oleh bash. Kutipan seperti
" '
akan berakhir pada variabel yang dihasilkan.Jika saya memberikan perlakuan yang sama dengan contoh sebelumnya, sepertinya ini:
$ echo
“I like to use
"'
"double quotes"
'"
sometimes
"sumber
Lihat printf ...
Tanpa menggunakan printf
Output: say "hai"
Menggunakan printf
Output: say \ "hai \"
sumber
printf
lolos lebih banyak karakter juga, seperti'
,(
dan)
printf %q
menghasilkan string yang siap untukeval
, tidak diformat untukecho -e
.printf
dengan penggunaan yang tidak bergunaecho
. Kedua contoh Anda telah salah mengutip. Perbaikan yang tepat adalah dengan memberi tanda kutip ganda variabel.Simpan karakter kutipan ganda sebagai variabel:
Keluaran:
sumber
Manfaatkan $ "string".
Dalam contoh ini, itu akan menjadi,
Catatan (dari halaman manual ):
sumber
Tambahkan
"\"
sebelum kutipan ganda untuk menghindarinya, bukan\
sumber
csh
jawaban untuk sebuahbash
pertanyaan? Keduanya sangat berbeda dan tidak kompatibel.