Como fazer um loop sobre as linhas de um arquivo?

47

Digamos que eu tenha este arquivo:

hello
world
hello world

Este programa

#!/bin/bash

for i in $(cat $1); do
    echo "tester: $i"
done

saídas

tester: hello
tester: world
tester: hello
tester: world

Gostaria de ter a for de iteração sobre cada linha individualmente ignorando espaços em branco, ou seja, as duas últimas linhas devem ser substituídas por

tester: hello world

Usando aspas for i in "$(cat $1)"; resulta em i sendo atribuído o arquivo inteiro de uma só vez. O que devo mudar?

    
por Tobias Kienzler 07.02.2011 / 11:28

1 resposta

56

Com for e IFS :

#!/bin/bash

IFS=$'\n'       # make newlines the only separator
set -f          # disable globbing
for i in $(cat < "$1"); do
  echo "tester: $i"
done

Note, entretanto, que ele irá ignorar as linhas vazias, pois nova linha é um caractere IFS-branco, as sequências contadas como 1 e as iniciais e posteriores são ignoradas. Com zsh e ksh93 (não bash ), você pode alterá-lo para IFS=$'\n\n' para que a nova linha não seja tratada especialmente, mas observe que todos os caracteres à direita da nova linha linhas vazias) serão sempre removidos pela substituição do comando.

Ou com read (não mais cat ):

#!/bin/bash

while IFS= read -r line; do
  echo "tester: $line"
done < "$1"

Lá, as linhas vazias são preservadas, mas observe que ela ignoraria a última linha se não estivesse adequadamente delimitada por um caractere de nova linha.

    
por 07.02.2011 / 11:39