Digamos que eu tenha duas variáveis no bash:
MULTILINE="I have
more than one line"
SINGLE_LINE="I only have one line
"
Quero detectar quando uma variável realmente contém mais de uma linha de texto, desconsiderando caracteres extras de nova linha à direita.
Então, é isso:
if [ some test on "$MULTILINE" ]; then echo 'yes'; else echo 'no'; fi
seria impresso yes
, e isso:
if [ some test on "$SINGLE_LINE" ]; then echo 'yes'; else echo 'no'; fi
iria imprimir no
.
Para o meu caso específico, acho que não preciso me preocupar com linhas em branco à esquerda, mas não faria mal saber como fazer isso.
Como posso fazer isso?
Respostas:
A solução mais simples que conheço é:
por exemplo:
==>
O item acima ignora todas as linhas em branco: inicial, final e interior. Mas observe que não é possível ter uma linha em branco interior, a menos que haja pelo menos duas linhas que não sejam em branco; portanto, sua existência não pode alterar a questão de saber se há mais de uma linha após aparar as linhas em branco à esquerda e à direita.
fonte
Consulte /programming/16414410/delete-empty-lines-using-sed
para obter mais informações sobre como aparar / excluir espaços em branco e linhas vazias usando sed.
Agora, escreva seu
if expression ...
uso entre$( ... )
aspas para obter o número de linhas e teste com o número:fonte
Uma ligeira modificação neste código deve fazê-lo. Você pode colocá-lo em seu próprio script para reutilizar assim:
Em seguida, você pode usá-lo dessa maneira (assumindo que você nomeou o script anterior
multiline-check.sh
):fonte
fi
. Infelizmente, estou preso no bash 3.1 (versão msysgit). Não vejo nada que pareça um erro de sintaxe para mim, mas obviamente estou perdendo alguma coisa. Pensamentos?Ignorando as linhas em branco à direita
Aqui está uma abordagem usando
awk
:Como funciona:
eco "$ TEST"
Isso pega qualquer variável do shell em que estamos interessados e a envia para o padrão.
tac
Isso reverte a ordem das linhas para que a última linha seja retornada primeiro. Após a execução
tac
, as linhas finais tornam-se as linhas principais.(O nome
tac
é o reverso decat
pelo motivo quetac
faz o quecat
faz, mas ao contrário.)awk 'f==0 && /./ {f=NR} END{if(f==NR){exit 0}; exit 1 }'
Isso armazena o número da primeira linha que não está em branco na variável
f
. Depois de ler todas as linhas, ele se comparaf
ao número total de linhasNR
,. sef
for igual aNR
, teríamos apenas uma única linha (ignorando espaços em branco iniciais) e sairemos com o código 0. Se houver uma ou mais linhas após a primeira linha em branco, ela sairá com o código `.&& echo "Found A Single Line"
Se
awk
sair com o código 0, aecho
instrução será executada.Ignorando linhas em branco iniciais e finais
Ao criar uma
awk
variável adicional , podemos estender o teste para ignorar as linhas em branco à esquerda e à direita:Como esta versão do
awk
código lida com espaços em branco à esquerda e à direita,tac
não é mais necessária.Tomando o
awk
código um pedaço de cada vez:first==0 && /./ {first=NR}
Se a variável
first
for zero (ou ainda não foi definida) e a linha tiver um caractere, qualquer caractere, definafirst
o número da linha. Quandoawk
terminar de ler as linhas,first
será definido como o número da linha da primeira linha que não estiver em branco././ {last=NR}
Se a linha tiver algum caractere, defina a variável
last
como o número da linha atual. Quandoawk
terminar de ler todas as linhas, essa variável terá o número da última linha que não estiver em branco.END{if(first==last){exit 0}; exit 1 }
Isso é executado depois que todas as linhas foram lidas. Se
first
for igual alast
, vimos zero ou linha linhas não em branco eawk
sai com o código0
. Caso contrário, ele sai com o código1
. O script de shell pode testar o código de saída normalmente comif
instruções ou&&
ou||
.fonte