Um dos erros mais comuns na criação de scripts bash em Linux ocorre quando se quer ler um arquivo linha por linha. A tendência é utilizar o comando loop for, que realiza a avaliação de cada palavra, não de cada linha. Nesse artigo, mostramos o método mais efetivo para fazer o que você precisa.
Com o loop for:
for line in $(cat file.txt); do echo "$line" ; done
Esta
é
a
linha
n°
1
Esta
é
a
linha
n°
2
[...]
Como podemos ver, o resultado não é o esperado. A solução é utilizar um loop while associado ao comando interno read. No entanto, você pode obter o mesmo resultado com um loop for se modificarmos a variável $IFS (Internal Field Separator - Separador do campo interno) antes de executar o loop. É o que veremos a seguir.
Como mencionado acima, o loop while continua a ser o método mais prático e simples para ler um arquivo linha por linha.
while read line; do
echo -e "$line\n";
done < file.txt
O resultado será:
Esta é a linha n° 1
Esta é a linha n° 2
Esta é a linha n° 3
Esta é a linha n° 4
Esta é a linha n° 5
A partir de um arquivo estruturado, também podemos obter os valores de cada campo e designá-los a diversas variáveis com o comando read. Porém, é preciso ter cuidado para designar à variável IFS o separador de campo adequado (por padrão, um espaço).
Exemplo:
#!/bin/bash
while IFS=: read user pass uid gid full home shell
do
echo -e "$full :\n\
Pseudo : $user\n\
UID :\t $uid\n\
GID :\t $gid\n\
Home :\t $home\n\
Shell :\t $shell\n\n"
done < /etc/passwd
while read i; do echo -e "configuração : $i"; done < <(echo -e "anabnc")
O loop while é o método mais simples, mas tem uma grande desvantagem: eliminar a formatação das linhas e, principalmente, dos espaços e tabulações. Felizmente, o loop for associado a uma mudança do IFS permite manter a estrutura do documento de saída.
oldIFS=$IFS # mantém o separador de campo
IFS=$'n' # novo separador de campo, o caractere de fim de linha
for linha in $(cat arquivo)
do
comando
done
IFS=$old_IFS # restabelece o separador de campo padrão
Foto: © ra2studio - 123RF.com