Итак, у меня есть список файлов в текстовом файле. Я считаю, что это около 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
Однако, это просто пытается скопировать мой корневой каталог в место назначения.
Как мне просто скопировать определенные файлы, в которые я хочу?
Вот немного сценария оболочки для Вас:
#!/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
я сделал [приблизительно 119], тестирование прежде, чем отправить этот ответ, но удостоверяются, что Вы пробуете его на меньшем образце сначала , чтобы подтвердить, что это работает как ожидалось!
Следующий сценарий сначала копирует структуру каталога с источника, тогда эти файлы из Вашего списка в соответствующие папки. Строка 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))
, Как использовать
Выполнение это:
python /path/to/move.py
Можно сделать это с 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
оба дают Вам то же число впоследствии.