Come aggiungere nuove righe quando si utilizza l'eco


42

Perché il comando seguente non inserisce nuove righe nel file generato e qual è la soluzione?

$ echo "Line 1\r\nLine2" >> readme.txt

$ cat readme.txt 
Line 1\r\nLine2

6
È echoobbligatorio? puoi usare printf.
Archemar,

Non sapevo di printf, con printf funziona: P ... quindi cosa fa non funzionare con echo allora?
Saeid Yazdani,

Includi \rnell'output o fa parte di CRLFNewline?
cuonglm,

9
Esistono diverse implementazioni di echocomando incompatibili tra loro. Pertanto si consiglia di utilizzare strumenti più standard come printf. Vedere unix.stackexchange.com/questions/65803/… per una panoramica estesa del problema.
jimmij,

Risposte:


38

echo


Una echorealizzazione che si conforma strettamente alla Single Unix Specification aggiungerà nuove righe se si fa:

echo 'line1\nline2'

Ma questo non è un comportamento affidabile. In realtà, c'è in realtà non è un comportamento standard che ci si può aspettare di echo.

OPERANDI

string

Una stringa da scrivere nell'output standard. Se il primo operando è -n, o se uno qualsiasi degli operandi contiene un carattere < \barra rovesciata> , i risultati sono definiti dall'implementazione .

Sui sistemi conformi XSI , se il primo operando è -n, deve essere trattato come una stringa, non un'opzione . Le seguenti sequenze di caratteri devono essere riconosciute su sistemi conformi XSI all'interno di uno qualsiasi degli argomenti:

\a- Scrivi un <allerta> .

\b- Scrivi un <backspace> .

\c- Sopprime il <newline> che altrimenti segue l'argomento finale nell'output. Tutti i caratteri che seguono gli \cargomenti devono essere ignorati.

\f- Scrivi un <feed di alimentazione> .

\n- Scrivi una <newline> .

\r- Scrivi un <carriage-return> .

\t- Scrivi un <tab> .

\v- Scrivi un <vertical-tab> .

\\- Scrivi un carattere <barra rovesciata> .

\0num- Scrivere un valore di 8 bit che è il numero ottale zero, uno, due o tre cifre num.

E quindi non c'è davvero alcun modo generale per sapere come scrivere una nuova riga echo, tranne per il fatto che in genere puoi fare affidamento solo echosul farlo.

Una bashshell in genere non è conforme alle specifiche e gestisce le -naltre opzioni, ma anche questo è incerto. Tu puoi fare:

shopt -s xpg_echo
echo hey\\nthere

hey
there

E nemmeno questo è necessario se bashè stato creato con l'opzione build-time ...

--enable-xpg-echo-default

Rende echopredefinito il carattere predefinito con caratteri di escape con barra rovesciata, senza richiedere l' -eopzione. Questo imposta il valore predefinito xpg_echodell'opzione shell su on, il che rende Bash echopiù simile alla versione specificata nella specifica Unix singola, versione 3. Vedi Bash Builtins , per una descrizione delle sequenze di escape che echoriconosce.


printf


D'altra parte, printfil comportamento è piuttosto docile in confronto.

FONDAMENTO LOGICO

L' printfutilità è stata aggiunta per fornire funzionalità storicamente fornite da echo. Tuttavia, a causa delle differenze inconciliabili tra le varie versioni di echoextant, la versione ha poche caratteristiche speciali, lasciando quelle a questa nuova printfutility, che si basa su una nel sistema della nona edizione.

La sezione DESCRIZIONE ESTESA corrisponde quasi esattamente alla printf()funzione dello standard ISO C, sebbene sia descritta in termini di notazione del formato file in Notazione formato file XBD .

Gestisce stringhe di formato che descrivono i suoi argomenti - che possono essere un numero qualsiasi di cose, ma per le stringhe sono praticamente o %bstringhe %syte o stringhe letterali . A parte gli %format nel primo argomento, si comporta come un %bargomento stringa yte, tranne per il fatto che non gestisce la \cfuga.

printf ^%b%s$ '\n' '\n' '\t' '\t'

^
\n$^    \t$

Vedi Perché è printfmeglio di echo? per più.


echo() printf


Potresti scrivere i tuoi standard conformi echocome ...

echo(){
    printf '%b ' "$@\n\c"
}

... che dovrebbe praticamente fare sempre la cosa giusta automaticamente.

In realtà, no ... Questo stampa un valore letterale \nalla fine degli argomenti se l'ultimo argomento termina con un numero dispari di <barre rovesciate> .

Ma questo non:

echo()
    case    ${IFS- } in
    (\ *)   printf  %b\\n "$*";;
    (*)     IFS=\ $IFS
            printf  %b\\n "$*"
            IFS=${IFS#?}
    esac

+1 per l' shopt -s xpg_echoopzione echoda utilizzare -eper impostazione predefinita.
Vignesh Raja,

Questa soluzione non funziona senza -e. Sono sorpreso che nessuno se ne sia accorto tranne forse @HaydeSchiff
ha9u63ar il

@ ha9u63ar - uhh ... hai letto questo?
Mikeserv,

27

Passa il flag -e all'eco per farlo analizzare i caratteri di escape come "\ r \ n", in questo modo:

echo -e "Line 1\r\nLine2" >> readme.txt

Una bella e semplice opzione "-e" per far funzionare le sequenze di escape - dice un'altra risposta che echonon è affidabile e non segue standard diversamente printf.
Edward,

1
Assicurati che il tuo script non contenga alcun letterale \ r \ n, come in un tr -d "\n"comando.
Noumenon,

8

In tutte le versioni di bash che ho usato, puoi semplicemente inserire una nuova riga letterale in una stringa in modo interattivo o in uno script, a condizione che la stringa sia sufficientemente citata.

interattivo:

$ echo "Line one
> Line two"
Line one
Line two
$

In uno script:

echo "Line one
Line two"

4
echo -e "Line 1\r\nLine2" >> readme.txt

ulteriori possibilità di utilizzo:

man echo

2

Le persone hanno già risposto adeguatamente, ma mi rifiuto di accettare un mondo in cui l'eco accetta qualsiasi opzione diversa da -n.

nl='
'
echo Line 1"$nl"Line 2"$nl"Line 3

1

Se hai un personaggio che non fa parte del messaggio, puoi passare attraverso sed

$ echo "Time on the next line:@$(date +"%Y-%m-%dT%T%z")" | sed -e's/@/\n/g'
Time on the next line:
2016-03-25T10:12:39-0500
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.