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.