Como adicionar novas linhas em variáveis no script bash

53

Quando faço

str="Hello World\n===========\n"

Também recebo o \n impresso. Como posso ter novas linhas então?

    
por Jiew Meng 03.09.2011 / 09:07

8 respostas

62

Em bash , você pode usar a sintaxe

str=$'Hello World\n===========\n'

Aspas simples precedidas por um $ é uma nova sintaxe que permite inserir seqüências de escape em strings.

Além disso, printf builtin permite salvar a saída resultante em uma variável

printf -v str 'Hello World\n===========\n'

Ambas as soluções não requerem um subshell.

Se, a seguir, você precisar imprimir a string, use aspas duplas, como no exemplo a seguir:

echo "$str"

porque quando você imprime a string sem aspas, a nova linha é convertida em espaços.

    
por 03.09.2011 / 09:55
29

Você pode colocar novas linhas literais entre aspas simples (em qualquer shell do tipo Bourne / POSIX).

str='Hello World
===========
'

Para uma sequência multilinha, os documentos aqui costumam ser convenientes. A string é alimentada como entrada para um comando.

mycommand <<'EOF'
Hello World
===========
EOF

Se você quiser armazenar a string em uma variável, use o comando cat em uma substituição de comando. Os caracteres de nova linha no final da string serão eliminados pela substituição do comando. Se você quiser manter as novas linhas finais, coloque uma rolha no final e retire-a depois. Em shells compatíveis com POSIX, você pode escrever str=$(cat <<'EOF'); str=${str%a} seguido pelo heredoc propriamente dito, mas o bash requer que o heredoc apareça antes do parêntese de fechamento.

str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}

Em ksh, bash e zsh, você pode usar o formulário $'…' entre aspas para expandir as escapadas entre aspas.

str=$'Hello World\n===========\n'
    
por 03.09.2011 / 13:02
6

Você está usando "echo"? Tente "echo -e".

echo -e "Hello World\n===========\n"
    
por 03.09.2011 / 09:13
3

De toda a discussão, aqui está a maneira mais simples para mim:

bash$ str="Hello World
==========="
bash$ echo "$str"
Hello World
===========

O comando echo deve usar aspas duplas .

    
por 24.12.2013 / 06:05
2

Se você precisar de novas linhas em seu script muitas vezes, poderá declarar uma variável global com uma nova linha. Dessa forma, você pode usá-lo em strings com aspas duplas (expansões variáveis).

NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
    
por 10.06.2013 / 09:27
1

Para complementar as grandes respostas existentes:

Se você usa bash e prefere usar novas linhas reais para facilitar a leitura , read é outra opção para capturar um aqui-doc em uma variável , que (como outras soluções aqui) não requer o uso de um subshell.

# Reads a here-doc, trimming leading and trailing whitespace.
# Use 'IFS= read ...' to preserve it (the trailing \n, here).
read -r -d '' str <<'EOF'   # Use 'IFS= read ...' to preserve the trailing \n
Hello World
===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"
[Hello World
===========]
  • -r garante que read não interprete a entrada (por padrão, isso traria barras invertidas como especiais, mas isso raramente é necessário).

  • -d '' define o delimitador "record" como uma string vazia, fazendo com que read leia a entrada inteira de uma só vez (em vez de apenas uma única linha).

Observe que, deixando o $IFS (o separador de campo interno) como padrão, $' \t\n' (um espaço, uma guia, uma nova linha), qualquer espaço em branco à esquerda e à direita é cortado do valor atribuído a $str , que inclui a nova linha final do here-doc.
(Note que mesmo que o corpo do here-doc inicie na linha após o delimitador start ( 'EOF' here), ele não contém um leading newline).

Geralmente, esse é o comportamento desejado, mas se você quiser essa nova linha, use IFS= read -r -d '' em vez de apenas read -r -d '' , mas observe que qualquer espaço em branco à esquerda e em branco é preservado.
(Observe que prefixar IFS=  diretamente ao comando read significa que a atribuição está em vigor apenas durante esse comando, portanto, não há necessidade de restaurar o valor anterior.)

Usar um aqui-doc também permite que você utilize opcionalmente o recuo para definir a sequência multilinha para legibilidade:

# Caveat: indentation must be actual *tab* characters - spaces won't work.
read -r -d '' str <<-'EOF' # NOTE: Only works if the indentation uses actual tab (\t) chars.
    Hello World
    ===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.
# Note how the leading tabs were stripped.
$ echo "$str"
[Hello World
===========]

Colocar - entre << e o delimitador de abertura here-doc ( 'EOF' , here) faz com que os caracteres de tabulação principais sejam removidos do corpo here-doc e até mesmo do delimitador de fechamento, mas note que este só funciona com real caracteres da aba , não em espaços, por isso, se o seu editor traduz pressionamentos de teclas de abas em espaços, é necessário trabalho extra.

    
por 08.07.2014 / 17:27
-1

você precisa fazer assim:

STR=$(echo -ne "Hello World\n===========\n")

Atualização:

Como Fred apontou, desta forma você perderá "\ n". Para atribuir uma variável com sequências de barra invertida expandida, faça:

STR=$'Hello World\n===========\n\n'

vamos testá-lo:

echo "[[$STR]]"

nos dá agora:

[[Hello World
===========

]]

Note que $ '' é diferente de $ "". O segundo faz a tradução de acordo com a localidade atual. Para ver a seção QUOTING em man bash .

    
por 03.09.2011 / 09:38
-1
#!/bin/bash

result=""

foo="FOO"
bar="BAR"

result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'

echo "$result"
printf '%s' "$result"

saída:

FOO
BAR

FOO
BAR
    
por 26.09.2016 / 11:37

Tags