Eu tenho uma string que é o resultado de alguma operação sobre a qual não tenho controle. Quando imprimo essa variável usando echo
, recebo:
echo $myvar
hello
No entanto, quando eu faço
if [ $myvar = "hello" ]; then
echo they are equal
else
echo they are not equal
fi
Eu sempre entendo que eles não são iguais. Eu suspeito que isso é por causa de um newline
personagem.
A corda também se comporta de maneira estranha. Quando eu faço:
newVAR="this is my var twice: "$myvar$myvar
echo $newVAR
Eu recebo:
hellois my var twice: hello
Como posso verificar se isso é de fato devido a um newline
e, em caso afirmativo, removê-lo?
printf '%q\n' "$string"
obter uma versão escapada de qualquer string. Por exemplo:printf '%q\n' 'foo\n'
->foo\\n
;printf '%q\n' $'foo\n'
->$'foo\n'
echo $foo
. Faça emecho "$foo"
vez disso.Respostas:
O problema é que você tem um retorno de carro incorporado (CR
\r
). Isso faz com que o ponto de inserção de texto do terminal volte ao início da linha que está imprimindo. É por isso que você está vendo o 'olá' no início da linha no$newVAR
exemplo -sed -n l
exibe uma visualização legível de caracteres não imprimíveis (e final de linha).Você pode testá-lo com uma verificação simples da condição do bash:
Você pode combinar o teste e corrigir em uma etapa testando
\r
(s) e removendo-os via:A correção usa a expansão de parâmetro do shell . O formulário específico usado acima é para substituir substrings com base no seu padrão fornecido:
${parameter/pattern/string}
<- Isso substitui apenas o primeiro padrão encontrado pela string na variável denominada * parâmetro. Para substituir todos os padrões, basta alterar o primeiro/
para//
.fonte
fix="....
linha?fix
pode servar
em si - ou muitas vezes você pode apenas usar a expansão de parâmetros como está, sem a necessidade de transferir o (possivelmente) valor modificado ..Você pode representar
\r
como$'\r'
no bash:Ou pique o último
\r
emmyvar
:fonte
Curiosamente, em muitas conchas
getopts
é um candidato muito provável para um trabalho como este. Isso pode parecer contra-intuitivo no começo, mas se você considerar quegetopts
'a função principal é reconhecer e oferecer a interpretação tantas opções de linha de comando de um caractere especificadas quanto as encontradas em uma série concatenada do mesmo, pode começar a se tornar um pouco mais sentido.Para demonstrar, a partir de um
bash
shell:Dessa forma, às vezes pode ser conveniente permitir
getopts
lidar com a desmontagem como uma espécie de piloto automático do shell para casos como este. Ao fazer isso, você pode apenas filtrar bytes indesejados com /case
ou[
testar]
e criar seu backup de string a partir do byte 1:Dado este exemplo de caso simples - e considerando um shell que suporta as expansões de parâmetros já mencionadas em outros lugares -, as expansões provavelmente servirão melhor aqui. Mas pensei
getopts
que valeria a pena mencionar também, caso você não estivesse ciente de suas capacidades nesse aspecto. Certamente, quando soube disso, encontrei muitos aplicativos úteis para ele, de qualquer maneira.fonte
Embora o Bash e outras linguagens de shell sejam úteis, às vezes é melhor usar uma linguagem de script verdadeira - como Perl. O Perl pode substituir scripts shell que chamam outros idiomas como sed e awk, bem como comandos UNIX com bastante facilidade. Aprendi isso há mais de 20 anos ao escrever scripts C-Shell que, por sua vez, chamavam sed, awk e vários comandos UNIX - antes de chamar o código FORTRAN. No Perl eu faria:
fonte