Come eseguire lescape di caratteri speciali in una stringa?

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 manipolazione It 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 sarebbe read -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.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *