从文件中列出的目录移动文件

Move files from directories listed in file

我的目录结构类似于下面的玩具示例

DirectoryTo
DirectoryFrom
-Dir1
---File1.txt
---File2.txt
---File3.txt
-Dir2
---File4.txt
---File5.txt
---File6.txt
-Dir3
---File1.txt
---File5.txt
---File7.txt

我正在尝试将所有文​​件从 DirectoryFrom 复制到 DirectoryTo,如果有重复则保留较新的文件。

DirectoryTo
-File1.txt
-File2.txt
-File3.txt
-File4.txt
-File5.txt
-File6.txt
-File7.txt
DirectoryFrom
-Dir1
---File1.txt
---File2.txt
---File3.txt
-Dir2
---File4.txt
---File5.txt
---File6.txt
-Dir3
---File1.txt
---File5.txt
---File7.txt

我创建了一个包含所有子目录列表的文本文件。此列表的顺序是最先列出最新的文件:

Filelist.txt

C:/DirectoryFrom/Dir1
C:/DirectoryFrom/Dir2
C:/DirectoryFrom/Dir3

所以我想做的是遍历 Filelist.txt 中的每个目录,复制文件,如果文件已经存在则不替换。

我想在命令行、shell 脚本或可能在 Python 中执行此操作。我是 Python 的新手,但对命令行有一点经验。但是,我从来没有做过这么复杂的事情。

实际上,我有大约 60 个文件夹,每个文件夹中有 50-200 个文件,让您感受一下我有多少。此外,每个文件约为 75MB。

我以前在 R 中做过类似的事情,但它很慢而且不是真正的目的。但这是我为 shell 脚本尝试过的内容,经过编辑以适合这个玩具示例:

#!/bin/bash

for line in Filelist.txt
do
    cp -n line C:/DirectoryTo/
done

如果您的 DirectoryFrom 中只有一级目录,那么您可以使用:

cp -n DirectoryFrom/*/* DirectoryTo

解释:如果DirectoryFrom的子目录中存在的每个文件不存在,则将其复制到DirectoryTo

n 标志用于不覆盖已存在的文件。

如果目录存在于 DirectoryTo

的子目录中,

cp 也会忽略目录

# Create test environnement :
mkdir C:/DirectoryTo
mkdir C:/DirectoryFrom
cd C:/DirectoryFrom
mkdir Dir1 Dir2 Dir3 
(
cat << EOF
Dir1/File1.txt
Dir1/File2.txt
Dir1/File3.txt
Dir2/File4.txt
Dir2/File5.txt
Dir2/File6.txt
Dir3/File1.txt
Dir3/File5.txt
Dir3/File7.txt
EOF
)| while read f
do
echo "$f : `date`" 
echo "$f : `date`" > $f
sleep 1
done


# create Filelist.txt file :
(
cat << EOF
C:/DirectoryFrom/Dir1
C:/DirectoryFrom/Dir2
C:/DirectoryFrom/Dir3
EOF
) > Filelist.txt


# Generate the liste of all files : 
cd C:/DirectoryFrom
cat Filelist.txt | while read f; do ls -1 $f; done | sort -u > filenames.txt
cat filenames.txt


# liste of all files path, sorted by time order :
cd C:/DirectoryFrom
ls -1tr */* > all_filespath_sorted.txt
cat all_filespath_sorted.txt


# selected files to be copied :
cat  filenames.txt | while read f; do cat all_filespath_sorted.txt | grep $f | tail -1 ; done


# copy of selected files:
cat  filenames.txt | while read f; do cat all_filespath_sorted.txt | grep $f | tail -1 ; done | while read c
do
echo $c
cp -p $c C:/DirectoryTo
done

# verifying :
cd C:/DirectoryTo
ls -ltr

# or
ls -1 | while read f; do echo -e "\n$f\n-------"; cat $f; done



#------------------------------------------------
# Other solution for a limited number of files :
#------------------------------------------------

# To list files by order :
find `cat  Filelist.txt | xargs` -type f | xargs ls -1tr 

# To copy files, the newer will replace the older :
find `cat  Filelist.txt | xargs` -type f | xargs ls -1tr | while read c
do
echo $c
cp -p $c C:/DirectoryTo
done