A maneira correta de processar arquivos em um loop em um script de shell é direcionar o comando para while
ou redirecionar um arquivo para a instrução done
de um loop while
. Isso manipulará qualquer nome, exceto aqueles que contiverem novas linhas. Você não deve usar o formulário for f in $(cmd)
.
Neste exemplo, find
é o comando que produz a lista de arquivos:
find . -type f -name "*.txt" | while read -r filename
do
if grep -qs "$string" "$filename" # or use >/dev/null 2>&1 instead of -qs
then
cp "$replacement" "$filename"
fi
done
ou, aqui, a lista está contida em um arquivo:
while read -r filename
...
done < "$file_with_list"
Outro método é usar xargs
.
Para um comando que produz a lista de arquivos (por exemplo, find
):
find . -type f -name "*.txt" -print0 | xargs -0 -I % env string=$string sh 'grep -qs "$string" "%" && cp replacement_file "%"'
O método anterior funcionará nos casos em que nomes de arquivos podem incluir novas linhas.
Se a lista estiver em um arquivo:
xargs -a "$file_with_list" -I % env string=$string sh 'grep -qs "$string" "%" && cp replacement "%"'
Todos esses exemplos funcionarão nos casos em que nomes de arquivos podem incluir espaços.