因此,我在文本文件中有一个文件列表。我相信它大约有 100,000 个文件。
该列表中的文件分布在许多目录中,具有不同的大小、文件名、扩展名、年龄等。
我正在尝试找到一种方法来将这些文件移动到另一个驱动器。
复杂因素:有些文件有相同的名称,但不是同一个文件。它们不能被移动到一个文件夹中,并且对多个文件采用覆盖或忽略策略。
最好,我希望它们保留它们的目录结构,但只在目标目录中保留我想要的文件。(目标驱动器不够大,无法简单地复制所有内容)。
下面是例子包含源文件名称的文本文件中的某些行:
media/dave/xdd/cruzer/F#(NTFS 1)/Raw Files/Portable Network Graphic file/3601-3900/FILE3776.PNG/Windows/winsxs/amd64_microsoft-windows-o..disc-style-memories_31bf3856ad364e35_6.1.7600.16385_none_51190840a935f980/Title_mainImage-mask.png
media/dave/xdd/d1/other/hd1/Program Files/DVD Maker/Shared/DvdStyles/Memories/Title_content-background.png
我曾尝试使用
rsync -av `cat /sourcefile.txt` /media/destinationhdd
它抱怨争论太多。
还
rsync -a --files-from=/sourcefile.txt / /media/destinationhdd
和
cat /sourcefile.txt | xargs -n 200 rsync -av % /media/destinationhdd
但是,这只是尝试将我的根目录复制到目的地。
我怎样才能复制我想要的特定文件?
答案1
这里有一个小的 shell 脚本:
#!/bin/sh
while read line
do
DIR=`dirname "$line"`
mkdir -p "$2/$DIR"
mv "$line" "$2/$DIR"
done < $1
用法(假设您将脚本保存为script.sh
并使用使其可执行chmod +x script.sh
):
./script.sh input.txt output_directory
它将使用原始路径将 中列出的所有文件移动input.txt
到中output_directory
,例如input.txt
具有以下列表:
test.txt
dir1/test.txt
Another Test/something_else.txt
文件将被移动到:
output_directory/test.txt
output_directory/dir1/test.txt
output_directory/Another Test/something_else.txt
我做到了一些在发布这个答案之前进行测试,但请确保先在较小的样本上尝试确认它按预期工作!
答案2
以下脚本首先复制目录结构从源头开始,然后文件从列表中复制到相应的文件夹中。此行if not line in ["", "\n"]
是为了防止文件列表包含空行时出现错误。
#!/usr/bin/env python
import os
import shutil
source = "/path/to/source"; target = "/path/to/target"; filelist = "/path/to/filelist.txt"
for root, dirs, files in os.walk(source):
for dr in dirs:
dr = root+"/"+dr
destdir = dr.replace(source, target)
if not os.path.exists(destdir):
os.makedirs(destdir)
with open(filelist) as lines:
src = lines.readlines()
for line in src:
if not line in ["", "\n"]:
shutil.copyfile(line.replace("\n", ""),
line.replace("\n", "").replace(source, target))
如何使用
- 将脚本复制到一个空文件中,保存为move.py
- 在头部添加适当的路径
运行方式:
python /path/to/move.py
答案3
您可以使用 xargs 轻松完成此操作。
mkdir /newroot/
<filenames.txt xargs -I% bash -c 'mkdir -p /newroot/$(dirname "%" && cp "%" "/newroot/%"'
困难的是确保新目录结构存在。为此,我们使用dirname
获取目录名称、mkdir -p
构建目录,最后cp
(或mv
)从一个目录复制/移动到另一个目录。我将其保留为复制模式,以便您可以测试。
我建议测试一下,find /newroot/ -type f | wc -l
然后wc -l filenames.txt
两者都会给出相同的数字。