As novas linhas são trocadas em alguns pontos porque são caracteres especiais. Para mantê-los, você precisa se certificar de que eles sejam sempre interpretados, usando aspas:
$ a="$(cat links.txt)"
$ echo "$a"
link1
link2
link3
Agora, como usei aspas sempre que estava manipulando os dados, os caracteres de nova linha ( \n
) sempre eram interpretados pelo shell e, portanto, permaneciam. Se você esquecer de usá-los em algum momento, esses caracteres especiais serão perdidos.
O mesmo comportamento ocorrerá se você usar o loop em linhas contendo espaços. Por exemplo, dado o seguinte arquivo ...
mypath1/file with spaces.txt
mypath2/filewithoutspaces.txt
A saída dependerá do uso ou não de citações:
$ for i in $(cat links.txt); do echo $i; done
mypath1/file
with
spaces.txt
mypath2/filewithoutspaces.txt
$ for i in "$(cat links.txt)"; do echo "$i"; done
mypath1/file with spaces.txt
mypath2/filewithoutspaces.txt
Agora, se você não quiser usar aspas, existe uma variável de shell especial que pode ser usada para alterar o separador de campo do shell ( IFS
). Se você definir este separador para o caractere de nova linha, você se livrará da maioria dos problemas.
$ IFS=$'\n'; for i in $(cat links.txt); do echo $i; done
mypath1/file with spaces.txt
mypath2/filewithoutspaces.txt
Por questão de integridade, aqui está outro exemplo, que não depende da substituição de saída do comando. Depois de algum tempo, descobri que esse método era considerado mais confiável pela maioria dos usuários devido ao próprio comportamento do utilitário read
.
$ cat links.txt | while read i; do echo $i; done
Aqui está um trecho da página de manual de read
:
The read utility shall read a single line from standard input.
Como read
obtém sua linha de entrada por linha, você tem certeza de que ela não será interrompida sempre que um espaço aparecer. Basta passar a saída de cat
através de um pipe, e iterará sobre suas linhas muito bem.
Editar: Eu posso ver de outras respostas e comentários que as pessoas estão bastante relutantes quando se trata do uso de cat
. Como jasonwryan disse em seu comentário, uma maneira mais correta de ler um arquivo em shell é usar o redirecionamento de fluxo ( <
), como você pode ver na resposta val0x00ff aqui . No entanto, como a pergunta não é " como ler / processar um arquivo na programação de shell ", minha resposta se concentra mais no comportamento das citações, e não no resto.