bash: Atribuindo a primeira linha de uma variável a uma variável

6

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?

    
por Almafeta 22.05.2015 / 12:21

4 respostas

6

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]}"
    
por 22.05.2015 / 12:38
6

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).

    
por 22.05.2015 / 13:52
4

pode não ser mais eficiente, mas um revestimento ...

firstLine='echo "${multiLineVariable}" | head -1'
    
por 27.08.2017 / 23:15
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]}"
    
por 22.05.2015 / 16:03

Tags