Como adicionar novas linhas ao usar o echo

41

Por que o seguinte comando não insere novas linhas no arquivo gerado e qual é a solução?

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

$ cat readme.txt 
Line 1\r\nLine2
    
por Saeid Yazdani 30.07.2015 / 16:31

6 respostas

37

echo

Uma implementação echo que esteja em conformidade com a Especificação Unix Única adicionará novas linhas se você:

echo 'line1\nline2'

Mas isso não é um comportamento confiável. Na verdade, não existe qualquer comportamento padrão que você possa esperar de echo .

OPERANDS

string

A string to be written to standard output. If the first operand is -n, or if any of the operands contain a <\backslash> character, the results are implementation-defined.

On XSI-conformant systems, if the first operand is -n, it shall be treated as a string, not an option. The following character sequences shall be recognized on XSI-conformant systems within any of the arguments:

\a - Write an <alert>.

\b - Write a <backspace>.

\c - Suppress the <newline> that otherwise follows the final argument in the output. All characters following the \c in the arguments shall be ignored.

\f - Write a <form-feed>.

\n - Write a <newline>.

\r - Write a <carriage-return>.

\t - Write a <tab>.

\v - Write a <vertical-tab>.

\ - Write a <backslash> character.

--enable-xpg-echo-default

Make the echo builtin expand backslash-escaped characters by default, without requiring the -e option. This sets the default value of the xpg_echo shell option to on, which makes the Bash echo behave more like the version specified in the Single Unix Specification, version 3. See Bash Builtins, for a description of the escape sequences that echo recognizes.

num
- Write an 8-bit value that is the zero, one, two, or three-digit octal number num.

    
  

E realmente não há uma maneira geral de saber como escrever uma nova linha com echo , exceto que você geralmente pode confiar em fazer echo para fazer isso.

Um shell bash normalmente não não está em conformidade com a especificação e lida com -n e outras opções, mas mesmo isso é incerto. Você pode fazer:

shopt -s xpg_echo
echo hey\nthere
hey
there

E nem mesmo que é necessário se bash foi criado com a opção de tempo de criação ...

RATIONALE

The printf utility was added to provide functionality that has historically been provided by echo. However, due to irreconcilable differences in the various versions of echo extant, the version has few special features, leaving those to this new printf utility, which is based on one in the Ninth Edition system.

The EXTENDED DESCRIPTION section almost exactly matches the printf() function in the ISO C standard, although it is described in terms of the file format notation in XBD File Format Notation.

printf

Por outro lado, o comportamento de printf é bastante manso em comparação.

%bl0ck_qu0te%

Ele lida com strings de formato que descrevem seus argumentos - o que pode ser qualquer coisa, mas para strings são ou %b yte strings ou literal %s trings. Diferentemente de %f oumats no primeiro argumento, ele se comporta mais como um argumento de string %b yte, exceto que ele não manipula o escape \c .

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

Veja Por que printf melhor que echo ? para mais.

echo() printf

Você pode escrever seus próprios padrões em conformidade com echo como ...

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

... o que deve sempre fazer a coisa certa automaticamente.

Na verdade, não ... Isso imprime um literal \n na cauda dos argumentos se o último argumento terminar em um número ímpar de < barras invertidas > .

Mas isso não acontece:

echo()
    case    ${IFS- } in
    (\ *)   printf  %b\n "$*";;
    (*)     IFS=\ $IFS
            printf  %b\n "$*"
            IFS=${IFS#?}
    esac
    
por 30.07.2015 / 17:07
23

Passe o sinalizador -e para fazer o eco para que ele analise os caracteres de escape como "\ r \ n", da seguinte forma:

echo -e "Line 1\r\nLine2" >> readme.txt
    
por 30.07.2015 / 16:37
6

Em todas as versões do bash que usei, você pode simplesmente inserir uma nova linha literal em uma string interativamente ou em um script, contanto que a string seja citada o suficiente.

Interativamente:

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

Em um script:

echo "Line one
Line two"
    
por 30.07.2015 / 21:40
4
echo -e "Line 1\r\nLine2" >> readme.txt

outras possibilidades de uso:

man echo
    
por 30.07.2015 / 16:37
2

As pessoas já responderam adequadamente, mas eu me recuso a aceitar um mundo onde o echo aceita qualquer opção diferente de -n .

nl='
'
echo Line 1"$nl"Line 2"$nl"Line 3
    
por 30.07.2015 / 20:36
1

Se você tem um personagem que não faz parte da mensagem, você pode canalizar através do 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
    
por 25.03.2016 / 16:14

Tags