Quando eu faço
str="Hello World\n===========\n"
Também recebo a \n
impressão. Como posso ter novas linhas então?
Quando eu faço
str="Hello World\n===========\n"
Também recebo a \n
impressão. Como posso ter novas linhas então?
Respostas:
Em bash
você pode usar a sintaxe
str=$'Hello World\n===========\n'
Aspas simples precedidas por a $
são uma nova sintaxe que permite inserir seqüências de escape em strings.
Também printf
embutido 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 você precisar imprimir a sequência a seguir, use aspas duplas, como no exemplo a seguir:
echo "$str"
porque quando você imprime a sequência sem aspas, a nova linha é convertida em espaços.
str=$'Hello World\n===========\n'
chamada a sintaxe ? substituição de variável?
zsh
e ksh
; no entanto, NÃO é compatível com POSIX.
str=$"My $PET eats:\n$PET food"
? Esta abordagem funciona para aspas duplas
Você pode colocar novas linhas literais entre aspas simples (em qualquer shell no estilo Bourne / POSIX).
str='Hello World
===========
'
Para uma sequência de múltiplas linhas, aqui os documentos geralmente são convenientes. A cadeia é alimentada como entrada para um comando.
mycommand <<'EOF'
Hello World
===========
EOF
Se você deseja armazenar a sequência em uma variável, use o cat
comando em uma substituição de comando. O (s) caractere (s) de nova linha no final da cadeia de caracteres será removido pela substituição do comando. Se você deseja manter as novas linhas finais, coloque uma tampa 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 exige que o heredoc apareça antes do parêntese de fechamento.
str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
No ksh, bash e zsh, você pode usar o $'…'
formulário entre aspas para expandir escapes de barra invertida dentro das aspas.
str=$'Hello World\n===========\n'
str=$(cat <<'EOF')
não funciona como está. As )
necessidades devem ser colocadas na próxima linha após o final do documento EOF
.. mas, mesmo assim, ele perde a nova linha à direita devido ao comando Substituição.
\n
instâncias finais (e principais) bash
ao capturar um documento aqui em uma variável, considere IFS= read -r -d '' str <<'EOF'...
como uma alternativa à abordagem de interrupção (veja minha resposta).
Você está usando "eco"? Tente "eco-e".
echo -e "Hello World\n===========\n"
echo
ele adicionará automaticamente um, a menos que você especifique -n. (No entanto, o principal problema da questão é como obter essas novas linhas em uma variável).
bash
, echo -e
faz o trabalho no OS X - que é porque echo
é uma festa builtin (em vez de um executável externo) e que builtin suporta -e
. (Como um builtin, ele deve funcionar em todas as plataformas que o bash é executado em, aliás, echo -e
trabalha em ksh
e zsh
também). Por outro lado, no entanto, o utilitário externoecho
no OS X - /bin/echo
- na verdade não suporta -e
.
Se você precisar de novas linhas em seu script muitas vezes, poderá declarar uma variável global que contém uma nova linha. Dessa forma, você pode usá-lo em cadeias de citação dupla (expansões variáveis).
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
$''
exigiria um subshell?
"My dog eats:${NL}dog food"
Para complementar as ótimas respostas existentes:
Se você estiver usando bash
e preferir usar novas linhas reais para facilitar a leitura , read
é outra opção para capturar um documento aqui 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, trataria barras invertidas especiais, mas isso raramente é necessário).
-d ''
define o delimitador "record" como uma string vazia, fazendo read
com que leia toda a entrada de uma só vez (em vez de apenas uma única linha).
Observe que, deixando $IFS
(o separador de campo interno) em seu padrão $' \t\n'
(um espaço, uma guia, uma nova linha), qualquer espaço em branco à esquerda e à direita é aparado a partir do valor atribuído a $str
, que inclui a nova linha à direita do documento.
(Observe que, embora o corpo do documento aqui inicie na linha após o delimitador de início ( 'EOF'
aqui), ele não contém uma nova linha principal ).
Geralmente, esse é o comportamento desejado, mas se você deseja essa nova linha à direita, use em IFS= read -r -d ''
vez de apenas read -r -d ''
, mas observe que qualquer espaço em branco à esquerda e à direita é preservado.
(Observe que anexar IFS=
diretamente ao read
comando significa que a atribuição está em vigor apenas durante esse comando, portanto, não há necessidade de restaurar o valor anterior.)
O uso de um documento aqui também permite que você use opcionalmente o recuo para ativar a cadeia de linhas múltiplas para facilitar a leitura:
# 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
===========]
A colocação -
entre <<
e o delimitador here-doc de abertura ( 'EOF'
, aqui) faz com que os caracteres de tabulação iniciais sejam retirados do corpo do doc here e até do delimitador de fechamento, mas observe que isso só funciona com caracteres de tabulação reais , não espaços, por isso, se você editor converte pressionamentos de tecla da guia em espaços, é necessário trabalho extra.
você precisa fazer assim:
STR=$(echo -ne "Hello World\n===========\n")
Atualizar:
Como Fred apontou, dessa maneira você perderá o "\ n" final. Para atribuir variáveis com as seqüências de barra invertida expandidas, faça:
STR=$'Hello World\n===========\n\n'
vamos testá-lo:
echo "[[$STR]]"
nos dá agora:
[[Hello World
===========
]]
Observe que $ '' é diferente de $ "". O segundo faz a tradução de acordo com a localidade atual. Para oital, consulte a seção CITAÇÕES em man bash
.
#!/bin/bash
result=""
foo="FOO"
bar="BAR"
result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'
echo "$result"
printf '%s' "$result"
resultado:
FOO
BAR
FOO
BAR
result+=$foo$'\n'
? $(printf %s "$foo")
apararia os caracteres de nova linha à direita, $foo
se houver.