
Conteúdo do arquivo.txt (sem estranheza, arquivo de texto conforme definido pelo POSIX)
iguana
gecko
anole
Roteiro de exemplo:
#!/bin/sh
string="$(cat file.txt)"
printf '%s' "$string"
Exemplo de saída:
[coolguy@somemachine ~]$ ./script.sh
iguana
gecko
anole[coolguy@somemachine ~]$
O que aconteceu com a última nova linha? Por que todas as novas linhas, exceto a última, são preservadas? Parece que não deveríamos usar echo para adicionar uma nova linha se já existisse uma lá.
Responder1
Não é a impressão, é a substituição do comando que faz isso. Está definido para fazer isso. DeDescrição POSIX:
O shell deve expandir a substituição do comando executando o comando em um ambiente subshell e substituindo a substituição do comando pela saída padrão do comando,removendo sequências de um ou mais caracteres {newline} no final da substituição.
Observe que ele removetodosnovas linhas à direita, não apenas uma.
Em um caso um tanto comum, você usaria a substituição de comando para capturar uma saída de uma linha, digamos osrev=$(uname -r)
. Os utilitários geralmente imprimem uma nova linha final, para conveniência do usuário na linha de comando. Mas em um script de shell, você pode querer usar essa string como parte de outra, digamos, um nome de arquivo: filename=blahblah-$osrev.dat
. E nesse caso, a nova linha final seria apenas um incômodo.
E, claro, um plano echo
adicionará uma nova linha final em qualquer caso.
Se você deseja que o conteúdo do arquivo esteja na variável, a solução alternativa comum é adicionar um caractere extra na substituição do comando e removê-lo posteriormente:
printf "foo\nbar\n\n" > file
string=$(cat file; echo x)
string=${string%x}
printf '%q\n' "$string"
que gera $'foo\nbar\n\n'
, mostrando ambas as novas linhas finais presentes.
Dependendo do que você pretende fazer com os dados, pode haver outras formas. Por exemplo, um while read
loop, ou Bash mapfile
, se você quiser processar o arquivo linha por linha.