Talvez haja outra maneira de arquivar o que você quer fazer, mas isso funciona
#!/bin/bash
STRINGTEST="
Onlygetthefirstline
butnotthesecond
orthethird
"
STRINGTEST=(${STRINGTEST[@]})
echo "${STRINGTEST[0]}"
Eu tenho uma variável multilinha e quero apenas a primeira linha dessa variável. O script a seguir demonstra o problema:
#!/bin/bash
STRINGTEST="Onlygetthefirstline
butnotthesecond
orthethird"
echo " Take the first line and send to standard output:"
echo ${STRINGTEST%%$'\n'*}
# Output is as follows:
# Onlygetthefirstline
echo " Set the value of the variable to the first line of the variable:"
STRINGTEST=${STRINGTEST%%$'\n'*}
echo " Send the modified variable to standard output:"
echo $STRINGTEST
# Output is as follows:
# Onlygetthefirstline butnotthesecond orthethird
Pergunta: Por que ${STRINGTEST%%$'\n'*}
retorna a primeira linha quando colocado após um comando echo
, mas substitui as novas linhas por espaços quando colocado após a atribuição?
Esse código funciona para mim com todas as versões do bash que eu tentei entre 2.05b e 4.3. É mais provável que você tenha tentado executar esse script com um shell diferente que não suporta a forma $'...'
de cotação.
Essa sintaxe $'...'
não é padrão sh
sintaxe (ainda) e só é suportada (a partir de 2015-05-22 e AFAIK) por ksh93
(onde foi originada), zsh
, bash
, versões recentes de mksh
e das sh
ou versões recentes do FreeBSD .
Minha aposta é que você tentou executar esse script com sh
em vez de bash
e seu sh
com base nas versões de ash
, pdksh
, yash
ou ksh88
que não suporte ainda.
Se você quiser tornar esse código POSIX 2008 compatível, será necessário escrevê-lo:
STRINGTEST="Onlygetthefirstline
butnotthesecond
orthethird"
NL='
'
STRINGTEST=${STRINGTEST%%"$NL"*}
printf '%s\n' "$STRINGTEST"
Então, você pode interpretá-lo por qualquer shell compatível com POSIX, como bash
, ou qualquer outro mais magro / rápido, como seu sh
.
(e lembre-se de que deixar uma variável sem aspas no contexto da lista tem um significado muito especial em shells semelhantes a Bourne).
pode não ser mais eficiente, mas um revestimento ...
firstLine='echo "${multiLineVariable}" | head -1'
Isso funciona para mim:
STRINGTEST="Some Text 1
Some Text 2
Some Text 3"
readarray -t lines < <(echo "$STRINGTEST")
echo "${lines[0]}"
E também funciona para linhas em branco:
STRINGTEST="
Some Text 1
Some Text 2
Some Text 3"
readarray -t lines < <(echo "$STRINGTEST")
echo "${lines[0]}"
Tags bash