Supponendo che $file
contenga un valore di un nome file, ad esempio Dr" A.tif
. Nella programmazione bash, come potrei sfuggire a virgolette singole e qualsiasi altro carattere speciale di $file
senza rimuovere il carattere speciale?
Aggiornamento del 9 luglio 2014
Come richiesta di @Gilles , seguente snippet di codice che non è in grado di gestire 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}
Dopo aver provato il risposta di @Patrick su line 1
, sembra funzionare per me. Ma se ho un file come Dr\^s A.tif
, printf
non sembra essere di aiuto, mi mostra Dr\^s\ A.tif
. Se provo manualmente su console in questo modo:
printf "%q" "Dr\^s A.tif"
avrò questo output:
Dr\\\^s\ A.tif
Qualche idea su come gestirla?
Commenti
- in cosa contesto ti aspetti di utilizzare $ file? o questo problema consiste nellassegnare la stringa con il carattere speciale a $ file?
- In realtà il comando find mi restituisce un array di elenco di file. E poi faccio scorrere questo elenco di file in $ file variable.
- ' hai ricevuto alcune risposte corrette qui, ma probabilmente non sono le risposte al domanda che ' stai veramente chiedendo. Dal tuo commento qui, sospetto fortemente che ' ti trovi sulla strada sbagliata. Non possiamo ' aiutarti molto perché continui a non mostrare il tuo codice. Tuttavia, ti consiglio di leggere Perché il mio script di shell si blocca su spazi o altri caratteri speciali? come sfondo. Mostra il tuo script e spiega cosa vuoi fare.
Rispondi
Tu può utilizzare il printf
integrato con %q
per farlo. Ad esempio:
$ file="Dr" A.tif" $ printf "%q\n" "$file" Dr\"\ A.tif $ file=" foo$bar\baz`" $ printf "%q\n" "$file" \ foo\$bar\\baz\`
Dalla documentazione di bash su 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)
Commenti
- Questo ' non funziona con alcuni casi quando devi conservare le virgolette.
- @ user3467349 funziona perfettamente con le virgolette. ' scommetto che ' stai provando qualcosa come
printf '%s' "foo"
. Devi prima capire come funziona lanalisi degli argomenti nella shell. Vedi gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 prima del # 6. - Potresti fornisci un esempio di questa stringa stampata con
printf
e nessunaltra manipolazioneIt doesn't have a: ""
- Il tuo problema non ha nulla a che fare con
printf
. Il tuo problema è che ' non vuoi che la shell analizzi la tua stringa. Per farlo, devi passare il tuo input alla shell in un modo in cui ' non provi nemmeno ad analizzarlo. Un modo per farlo sarebberead -r -p 'input: ' && printf '%q\n' "$REPLY"
e fornire linput quando richiesto. - Come ho detto ' molte volte adesso. Non sapere come passare i dati grezzi alla shell non è ' un problema con
printf
. Forse dovresti fare una domanda piuttosto che criticare una soluzione che non ha nulla a che fare con il tuo problema.
Risposta
Prova: –
file=Dr\"\ A.tif echo $file Dr" A.tif
o
file="Dr" A.tif" echo $file Dr" A.tif
o se la stringa contiene un doppio quote: –
file="Dr" A.tif" echo $file Dr" A.tif
Ci sono buoni tutorial sullescape e la citazione in rete. Inizia con questo .
Risposta
Non “Non è necessario eseguire lescape dei nomi di file che stai gestendo in uno script. Lescape è necessario solo se desideri inserire un nome di file come letterale in uno script o per passare diversi nomi di file come un unico flusso di input in un altro script.
Dato che stai “ripetendo loutput di find
, questo è uno dei modi più semplici (!) per gestire ogni percorso possibile :
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" {} +)
Risposta
veloce e (molto) sporco
find . | sed "s/^/"/" | sed "s/$/"/"
Risposta
Molte di queste risposte, inclusa quella con la votazione più alta, utilizzando printf "%q"
non funziona in tutti i casi senza ulteriori manipolazioni.Suggerirei quanto segue (esempio sotto):
cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn"t contain lexemes: "" EOF
Commenti
- Scusa la domanda n00b ma puoi approfondire come useresti effettivamente questo per eseguire lescape dei caratteri in una stringa? Se copio il codice che scrivi nel mio terminale, stampa solo 2015-11-07T03: 34: 41Z app [postgres.0000]: [TAG] la query di ricerca di testo non ' t contengono lessemi: " " … non è stato eseguito alcun escape.
- Questo ' è letteralmente il punto, tutti i caratteri speciali sono interpretati come caratteri letterali non per il loro significato speciale. Prova a echo " la stringa precedente " invece di vedere la differenza.