Como é str=$'Hello World\n===========\n'chamada a sintaxe ? substituição de variável?
Zengr 10/08/13
5
@zengr: É chamado de citação ANSI-C , e também é suportado em zshe ksh; no entanto, NÃO é compatível com POSIX.
precisa saber é o seguinte
4
@ mkelement0, vem de ksh93, também é suportado pelo zsh, festança, mksh e sh FreeBSD, e sua inclusão na próxima grande revisão do POSIX é em discussão
Stéphane Chazelas
11
Não parece funcionar com aspas duplas? por exemplo str=$"My $PET eats:\n$PET food"? Esta abordagem funciona para aspas duplas
Brad Parks
31
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'HelloWorld===========
EOF
Se você deseja armazenar a sequência em uma variável, use o catcomando 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'HelloWorld===========
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.
Estou usando o GNU bash 4.1.5 e 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.
precisa saber é o seguinte
@ fred Bons pontos, expliquei sobre as novas linhas à direita e mostrei o código que funciona no bash. Eu acho que é um bug no bash, embora, para ser honesto, ao reler a especificação POSIX, não seja claro que o comportamento seja obrigatório quando o << estiver dentro de uma substituição de comando e o heredoc não.
Gilles 'SO- stop be evil'
Coisas boas; para preservar as \ninstâncias finais (e principais) bashao 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).
Entre. Você não precisa do final \ n, porque echoele 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).
precisa saber é o seguinte
+1 De todas as soluções, esta é a mais direta e mais simples.
Hai Vu
echo -e não funciona no OS X
Greg M. Krsak 04/04
2
@GregKrsak: In bash, echo -efaz 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 -etrabalha em kshe zshtambém). Por outro lado, no entanto, o utilitário externoecho no OS X - /bin/echo- na verdade não suporta -e.
usar o seguinte comando
4
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}"
Agradável! Isso pode ser incluído em variáveis usando aspas duplas, por exemplo"My dog eats:${NL}dog food"
Brad Parks
Isso funcionou para mim. Ao usar um script bash para compor uma sequência que é automaticamente copiada na área de transferência para colar posteriormente em outro lugar, essa abordagem funcionou para adicionar novas linhas na saída resultante.
Ville
3
De todas as discussões, aqui está a maneira mais simples para mim:
bash$ str="Hello World
==========="
bash$ echo "$str"HelloWorld===========
Se você estiver usando bashe 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 \nHelloWorld===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"[HelloWorld===========]
-rgarante que readnã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 readcom 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 readcomando 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.HelloWorld===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.# Note how the leading tabs were stripped.
$ echo "$str"[HelloWorld===========]
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.
Respostas:
Em
bash
você pode usar a sintaxeAspas 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ávelAmbas 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:
porque quando você imprime a sequência sem aspas, a nova linha é convertida em espaços.
fonte
str=$'Hello World\n===========\n'
chamada a sintaxe ? substituição de variável?zsh
eksh
; no entanto, NÃO é compatível com POSIX.str=$"My $PET eats:\n$PET food"
? Esta abordagem funciona para aspas duplasVocê pode colocar novas linhas literais entre aspas simples (em qualquer shell no estilo Bourne / POSIX).
Para uma sequência de múltiplas linhas, aqui os documentos geralmente são convenientes. A cadeia é alimentada como entrada para um comando.
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 escreverstr=$(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.No ksh, bash e zsh, você pode usar o
$'…'
formulário entre aspas para expandir escapes de barra invertida dentro das aspas.fonte
str=$(cat <<'EOF')
não funciona como está. As)
necessidades devem ser colocadas na próxima linha após o final do documentoEOF
.. 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, considereIFS= read -r -d '' str <<'EOF'...
como uma alternativa à abordagem de interrupção (veja minha resposta).Você está usando "eco"? Tente "eco-e".
fonte
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 é porqueecho
é 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 emksh
ezsh
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).
fonte
$''
exigiria um subshell?"My dog eats:${NL}dog food"
De todas as discussões, aqui está a maneira mais simples para mim:
O comando echo deve usar aspas duplas .
fonte
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.-r
garante queread
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, fazendoread
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 apenasread -r -d ''
, mas observe que qualquer espaço em branco à esquerda e à direita é preservado.(Observe que anexar
IFS=
diretamente aoread
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:
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.fonte
você precisa fazer assim:
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:
vamos testá-lo:
nos dá agora:
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
.fonte
resultado:
fonte
result+=$foo$'\n'
?$(printf %s "$foo")
apararia os caracteres de nova linha à direita,$foo
se houver.