2015-07-04 12 views
7

Il seguente script ceduta un'uscita inaspettata:Come faccio a uscire da una serie di backslash in una bash printf?

printf "escaped slash: \\ \n" 
printf "2 escaped slashes: \\\\ \n" 
printf "3 escaped slashes: \\\\\\ \n" 
printf "4 escaped slashes: \\\\\\\\ \n" 

Esegui come uno script bash sotto Ubuntu 14, vedo:

escaped slash: \ 
2 escaped slashes: \ 
3 escaped slashes: \\ 
4 escaped slashes: \\ 

Err .. cosa?

risposta

4

Supponendo che printfFORMAT stringa è circondato da virgolette doppie, printf prende un ulteriore livello di espansione, rispetto ad esempio echo (entrambi i comandi incorporati nella shell).

Cosa vi aspettate da printf può effettivamente essere raggiunto utilizzando apici:

printf '1 escaped slash: \\ \n' 
printf '2 escaped slashes: \\\\ \n' 
printf '3 escaped slashes: \\\\\\ \n' 
printf '4 escaped slashes: \\\\\\\\ \n' 

uscite:

1 escaped slash: \ 
2 escaped slashes: \\ 
3 escaped slashes: \\\ 
4 escaped slashes: \\\\ 
+0

Nota: questo funziona perché si impedisce a 'bash' di rimuovere i backslash prima che' printf' veda l'argomento. – chepner

+0

@chepner: sono d'accordo. Sembra che l'ordine di valutazione sia: 1) 'bash' espande la stringa' FORMAT' * (solo se circondata da virgolette doppie!) *. 2) 'printf' combina' ARGUMENTS' e 'FORMAT' in una stringa. 3) La stringa finale viene nuovamente espansa (cioè \\ diventa \). 4) Il risultato è finalmente stampato. –

+0

Chiudi; 'printf' elabora solo il' FORMAT' prima di inserire gli argomenti; confronta 'printf '\ n'' con' printf'% s '' \ n''. – chepner

3

printf è un built-in bash. Guarda help printf:

 
printf [-v var] format [arguments] 
     Formats and prints ARGUMENTS under control of the FORMAT. 

si dovrebbe passare il formato e l'argomento. Quindi aggiungere il formato "%s\n" prima che l'argomento:

printf "%s\n" "escaped slash: \\" 
printf "%s\n" "2 escaped slashes: \\\\" 
printf "%s\n" "3 escaped slashes: \\\\\\" 
printf "%s\n" "4 escaped slashes: \\\\\\\\" 

uscita:

 
escaped slash: \ 
2 escaped slashes: \\ 
3 escaped slashes: \\\ 
4 escaped slashes: \\\\ 
+0

@Yuri G .: Grazie per la descrizione aggiuntiva. – Cyrus

+0

Nota: questo funziona perché si evita che 'printf' applichi un altro giro di interpretazione dei backslash. – chepner

Problemi correlati