Bir karakter dizisindeki özel karakterlerden nasıl kaçılır?


16

Varsayarsak $filebir dosya adının bir değeri tutan, demek Dr' A.tif. Bash programlamada, özel karakteri $filekaldırmadan tek tırnak ve diğer özel karakterlerden nasıl kaçabilirim ?

9 Temmuz 2014 Güncellemesi

As @Gilles talebi kolu mümkün değildir kod parçacığı ardından, 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}

Ben denedim sonra @Patrick gelen cevap üzerine line 1, bu benim için işe görünmektedir. Ama eğer böyle bir dosyam varsa Dr\^s A.tif,printf komut yardımcı görünmüyor, bana gösteriyor Dr\^s\ A.tif. El ile konsolda böyle denerseniz:

printf "%q" "Dr\^s A.tif"

Ben bu çıktı olacak:

Dr\\\^s\ A.tif

Bunun nasıl ele alınacağı hakkında bir fikrin var mı?


3
hangi bağlamda $ dosyasını kullanmayı bekliyorsunuz? veya özel karakterli dizeyi $ dosyasına mı ataıyor?
rob

Aslında find komutu bana bir dizi dosya listesi döndürüyor. Ve sonra bu dosya listesinde $ file değişkenine dönüyorum.
huahsin68

2
Burada size bazı doğru cevaplar verilmiştir, ancak muhtemelen gerçekten sorduğunuz sorunun yanıtları değildir. Buradaki yorumunuzdan yanlış yolda olduğunuzdan şüpheleniyorum. Kodunuzu göstermediğiniz için size çok yardımcı olamayız. Ancak benim kabuk komut dosyası neden boşluk veya diğer özel karakterler boğuluyor okumanızı öneririz. arka plan olarak. Senaryonuzu gösterin ve ne yapmak istediğinizi açıklayın.
Gilles 'SO- kötü olmayı kes'

Yanıtlar:


14

Bunu yapmak için printfyerleşik ile birlikte %qkullanabilirsiniz. Örneğin:

$ file="Dr' A.tif"
$ printf '%q\n' "$file"
Dr\'\ A.tif

$ file=' foo$bar\baz`'
$ printf '%q\n' "$file"
\ foo\$bar\\baz\`

Aşağıdakilerdeki bash belgelerinden printf:

In addition to the standard format specifications described in printf(1)
and printf(3), printf interprets:

 %b       expand backslash escape sequences in the corresponding argument
 %q       quote the argument in a way that can be reused as shell input
 %(fmt)T  output the date-time string resulting from using FMT as a format
          string for strftime(3)

Bu, çift tırnakları korumanız gerektiğinde belirli durumlarda .eg ile çalışmaz.
user3467349

@ user3467349 tırnak işaretleri ile iyi çalışıyor. Bahse girerim gibi bir şey deniyorsun printf '%s' "foo". Önce argüman ayrıştırma işleminin kabukta nasıl çalıştığını anlamanız gerekir. Bkz. Gnu.org/software/bash/manual/bash.html#Shell- # 6 numaralı işlemden önce.
Patrick

Bu dizeye bir örnek printfIt doesn't have a: ""
verebilir misiniz

Sorununuzla hiçbir ilgisi yok printf. Sorununuz, kabuğun dizenizi ayrıştırmasını istememenizdir. Bunu yapmak için, girdinizi ayrıştırmaya çalışmadığı bir şekilde kabuğa geçirmeniz gerekir. Bunu yapmanın bir yolu read -r -p 'input: ' && printf '%q\n' "$REPLY", istendiğinde girişi sağlamaktır.
Patrick

1
Şimdi birkaç kez söylediğim gibi. Ham verilerin kabuğa nasıl aktarılacağını bilmemek sorun değil printf. Belki probleminizle ilgisi olmayan bir çözümü eleştirmek yerine bir soru sormalısınız.
Patrick

4

Deneyin:-

file=Dr\'\ A.tif
echo $file
Dr' A.tif

veya

file="Dr' A.tif"
echo $file
Dr' A.tif

veya dizede çift tırnak varsa: -

file='Dr" A.tif'
echo $file
Dr" A.tif

İnternetten kaçma ve alıntı yapma konusunda iyi öğreticiler vardır. İle başlayın bu bir .


1

Bir komut dosyasında işlediğiniz dosya adlarından kaçmanıza gerek yoktur. Kaçış yalnızca bir komut dosyasına bir dosya adı hazır bilgi olarak koymak veya birkaç dosya adını tek bir giriş akışı olarak başka bir komut dosyasına geçirmek istiyorsanız gereklidir .

Çıktısında döngü yaptığınızdan find, bu olası her yolu işlemek için en basit yollardan biridir (!) :

while IFS= read -r -d ''
do
    file_namex="$(basename -- "$REPLY"; echo x)"
    file_name="${file_namex%$'\nx'}"
    do_something -- "$file_name"
done <(find "$some_path" -exec printf '%s\0' {} +)

0

hızlı ve (çok) kirli

find . | sed 's/^/"/' | sed 's/$/"/'

-1

En çok oy alanı da dahil olmak üzere bu cevapların çoğu, printf "%q"ek manipülasyon olmadan tüm durumlarda çalışmayacaktır. Aşağıdakileri öneririm (aşağıdaki örnek):

cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn't contain lexemes: "" EOF


N00b sorusunu özür dilerim ama bunu bir karakter dizisinden kaçmak için nasıl kullanacağınız hakkında ayrıntılı bilgi verebilir misiniz? Yazdığım kodu terminalime kopyalarsam 2015-11-07T03: 34: 41Z app [postgres.0000]: [TAG] metin arama sorgusu lexem içermez: "" ... hiçbir şey kaçmaz .
SharkAlley

Bu tam anlamıyla nokta, tüm özel karakterler , özel anlamları için değil, gerçek karakterler olarak yorumlanır. Farkı görmek için "yukarıdaki dizeyi" yankılamaya çalışın .
user3467349
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.