Com zsh , você poderia fazer:
files=(${(f)"$(cut -d , -f 1 <movies.csv)"})
glob=('$files['{1..$#files}']')
eval "tocopy=(Movies/**/(${(j:|:)glob})(D.))"
print -rl -- $tocopy # to check it's OK
cp -i -- $tocopy Sorted_Media/
Explicado:
-
cut -d , -f1 < movies.csv : recupera a primeira coluna do csv (um nome de arquivo por linha).
-
${(f)"$(cmd)"} : divida a saída de cmd nos feeds de linha ( $files agora é uma matriz com todos os nomes de arquivos).
-
glob=('$files['{1..$#files}']') : cria outra matriz com elementos literalmente $files[1] , $files[2] ...
-
${(j:|:)array} : junte os elementos da matriz com | , então estamos basicamente avaliando o comando tocopy=(Movies/**/($files[1]|$files[2]|...|$files[n])(DN.)) (onde n é o número de elementos na matriz $files ).
-
**/ : globalização recursiva (procure pelos arquivos em qualquer nível de subdiretórios).
-
(D.) : qualificadores glob (procure em diretórios ocultos também (D), somente arquivos regulares (.))
Ou com ferramentas GNU:
find Movies -type f -print0 |
awk '
!d {f[$1]; next}
$NF in f {
delete f[$NF]
print
}' FS=, file.csv d=1 FS=/ RS='files=(${(f)"$(cut -d , -f 1 <movies.csv)"})
glob=('$files['{1..$#files}']')
eval "tocopy=(Movies/**/(${(j:|:)glob})(D.))"
print -rl -- $tocopy # to check it's OK
cp -i -- $tocopy Sorted_Media/
' ORS='find Movies -type f -print0 |
awk '
!d {f[$1]; next}
$NF in f {
delete f[$NF]
print
}' FS=, file.csv d=1 FS=/ RS='%pre%' ORS='%pre%' - |
xargs -r0 cp -vt Sorted_Media/
' - |
xargs -r0 cp -vt Sorted_Media/
Usando delete , garantimos que apenas a primeira instância (se houver vários arquivos com o mesmo nome) seja copiada. -i na solução zsh é para lhe dar uma chance de decidir o que fazer se houver um conflito. Não podemos usar -i aqui porque o stdin de cp não é mais o terminal.
Substitua cp por echo cp se você quiser apenas verificar o que estaria fazendo sem realmente fazer isso.