com zsh
:
src=(${(f)"$(<src.txt)"})
for f (${(f)"$(<dest.txt)"})
(($src[(Ie)$f:t])) && mv /src/dir/$f:t $f
Isto lê cada arquivo em uma matriz e, em seguida, para cada elemento na matriz "dest" , se o nome da base ( :t
for um modificador zsh
que remove todos os componentes principais do caminho) também está no array "src" e move o arquivo.
Para executar uma execução a seco, substitua mv
por printf '"%s" -> "%s"\n'
.
Agora, você também pode executar (ainda em zsh
):
for f (${(f)"$(grep -Ff src.txt dest.txt)"})
mv /src/dir/$f:t $f
que funciona bem, desde que nenhum dos nomes de arquivo em src.txt
corresponda a nenhum dos nomes de diretório (ou parte desse nome) na lista de caminhos em dest.txt
(por exemplo, um nome de arquivo data1
in src.txt
e um caminho como /path/data1_dir/some_file
in dest.txt
daria um falso positivo). Para evitar isso, você poderia passar os nomes dos arquivos para grep
como padrões (ou seja, usando regex como /filename$
) em vez de F
ixed para corresponder apenas ao último componente dos caminhos em dest.txt
. Embora isso exija a exclusão de todos os caracteres especiais (se houver) nos nomes de arquivos em src.txt
, por exemplo, desta vez com bash
( 4
):
readarray -t files < <(sed 's|[[\.*^$/]|\&|g;s|.*|/&$|' src.txt | grep -f- dest.txt)
for f in "${files[@]}"; do mv /src/dir/"${f##*/}" "$f"; done