Você pode evitar o loop bash lento com algo assim, o que parece funcionar bem em meus testes:
$ tr '\n' 'cat file1 |xargs -d'\n' -I{} echo "mv -vt path/to/deny " {}
' <file1 |xargs -0 -I{} mv -vt path/to/deny {} #v for verbose.
#OR
$ cat file1 |xargs -d'\n' -I{} mv -vit path/to/deny {} # set delimiter to new line
Para uma corrida seca, você pode fazer um teste como este
$ while IFS= read -r dir; do folders+=("$dir");done < list.txt
$ mv -t path/to/Deny_folder -- "${folders[@]}" #-R is not available in Red Hat and Debian
PS: Meu comando mv
no RHEL & Debian não reconhece a opção -R em mv.
Uma armadilha dessa solução é se os nomes de diretório em seu arquivo incluírem novas linhas como parte de seu dirname. Em todos os outros casos (ou seja, nomes de dir com espaços), ambas as versões foram testadas e funcionam bem.
Se você quiser fazer isso com um loop, você pode acelerar as coisas evitando chamar o mv para cada linha lida pelo seu arquivo. Você poderia "carregar" todas as linhas / diretórios em uma matriz e chamar mv depois, como:
while IFS= read -r dir; do
let "a++"
folders+=("$dir")
[ "$a" -gt 1000 ] && mv -vt path/to/Deny_folder -- "${folders[@]}" && a=1 && unset folders
done < list.txt
Ou até mesmo fazer um tipo de agrupamento mv:
$ tr '\n' 'cat file1 |xargs -d'\n' -I{} echo "mv -vt path/to/deny " {}
' <file1 |xargs -0 -I{} mv -vt path/to/deny {} #v for verbose.
#OR
$ cat file1 |xargs -d'\n' -I{} mv -vit path/to/deny {} # set delimiter to new line