A maneira mais simples é ler os nomes dos arquivos usando um loop de shell e, em seguida, executar vários comandos find
em segundo plano:
while IFS= read -r file; do
find /mnt/SAN/documents/ -type f -name "$file" &
done < fileList.txt > foundFiles.txt
Isso, no entanto, lançará mais de 200 mil instâncias de find
e provavelmente deixará sua máquina de joelhos. Uma abordagem melhor seria criar um comando find
complexo, fornecendo a cada nome de arquivo:
$ printf 'find /mnt/SAN/documents/ -type f '; while IFS= read -r file; do printf -- '-name "%s" -o ' "$file"; done < fileList.txt | sed 's/-o $/\n/'
find /mnt/SAN/documents/ -type f -name "49" -o -name "50" -o -name "51" -o -name "52"
Você pode então executar o próprio comando copiando / colando-o ou com:
eval $(printf 'find /mnt/SAN/documents/ -type f '; \
while IFS= read -r file; do
printf -- '-name "%s" -o ' "$file"; done < fileList.txt |
sed 's/-o $/\n/')
No entanto, isso também será interrompido se você tiver muitos arquivos, portanto, será necessário executá-lo em lotes:
for i in $(seq 1 100 $(wc -l < fileList.txt)); do
k=$((i+100));
printf 'find /mnt/SAN/documents/ -type f ';
sed -n "$i,${k}p" fileList.txt |
while IFS= read -r file; do
printf -- '-name "%s" -o ' "$file";
done | sed 's/-o $/\n/';
done
Isso criará comandos find
separados para cada lote de 100 arquivos em sua lista, que você pode executar com eval
, como mostrado acima, ou apenas salvar em um arquivo e executar o arquivo:
for i in $(seq 1 100 $(wc -l < fileList.txt)); do
k=$((i+100));
printf 'find /mnt/SAN/documents/ -type f ';
sed -n "$i,${k}p" fileList.txt |
while IFS= read -r file; do
printf -- '-name "%s" -o ' "$file";
done | sed 's/-o $/\n/';
done > script.sh && bash script.sh > foundFiles.txt
Note que a abordagem de Stéphane , começando com arquivos existentes e verificando quais estão faltando, certamente seria melhor aqui ( a menos que os arquivos existentes sejam mais do que os arquivos ausentes). Em uma veia semelhante, você poderia primeiro criar uma lista de todos os arquivos existentes e então usar comm
para compará-los à lista de arquivos de destino (já que você diz que tem uma lista de arquivos, assumirei que seus nomes nunca contém caracteres de nova linha):
find /mnt/SAN/documents/ -type f | sort > found
comm -13 <(sort found) <(sort fileList.txt)
O comando comm
imprimirá todas as linhas que estão em fileList.txt
, mas não em found
.