Скрипт для копирования файлов на CD, а не на жесткий диск в новый каталог - PullRequest
0 голосов
/ 12 апреля 2010

Мне нужно скопировать файлы с набора компакт-дисков, которые содержат много дублирующегося контента, друг с другом и с тем, что уже находится на моем жестком диске. Имена файлов идентичных файлов не совпадают и находятся в подкаталогах с разными именами. Я хочу скопировать неповторяющиеся файлы с компакт-диска в новый каталог на жестком диске. Меня не волнуют подкаталоги - я разберусь позже - я просто хочу уникальные файлы.

Я не могу найти программное обеспечение для этого - см. Мой пост в SuperUser https://superuser.com/questions/129944/software-to-copy-non-duplicate-files-from-cd-dvd

Кто-то в SuperUser предложил мне написать скрипт, использующий GNU "find" и версию Win32 некоторых инструментов для контрольной суммы. Я посмотрел на это и ничего подобного не делал раньше. Я надеюсь, что есть что-то, что я могу изменить.

Я нашел хорошую программу для удаления дубликатов, Duplicate Cleaner (она сравнивает контрольные суммы), но она мне здесь не поможет, так как мне пришлось бы копировать все компакт-диски на диск, и каждый, вероятно, содержит около 80% дубликатов. и у меня нет места для этого - мне пришлось бы циклически перебирать по нескольку раз, копируя все, затем поворачиваясь и удаляя 80% всего этого, много работая на жестком диске.

Спасибо за любую помощь.

1 Ответ

0 голосов
/ 13 апреля 2010

Я не использую Windows, но я дам предложение: комбинация GNU find и сценария Lua. Для find вы можете попробовать

find / -exec md5sum '{}' ';'

Если ваше программное обеспечение GNU включает xargs, то следующее будет эквивалентно, но может быть значительно быстрее:

find / -print0 | xargs -0 md5sum

Это даст вам список контрольных сумм и соответствующих имён файлов. Мы выбросим имена файлов и сохраним контрольные суммы:

#!/usr/bin/env lua

local checksums = {}

for l in io.lines() do
  local checksum, pathname = l:match('^(%S+)%s+(.*)$')
  checksums[checksum] = true
end

local cdfiles = assert(io.popen('find e:/ -print0 | xargs -0 md5sum'))

for l in cdfiles:lines() do
  local checksum, pathname = l:match('^(%S+)%s+(.*)$')
  if not checksums[checksum] then
    io.stderr:write('copying file ', pathname, '\n')
    os.execute('cp ' .. pathname .. ' c:/files/from/cd')
    checksums[checksum] = true
  end
end

Затем вы можете передать вывод из

find / -print0 | xargs -0 md5um

в этот скрипт.

Есть несколько проблем:

  • Если имя файла содержит специальные символы, его необходимо заключить в кавычки. Я не знаю соглашений о цитировании в Windows.

  • Было бы более эффективно записывать контрольные суммы на диск, а не постоянно выполнять поиск. Вы можете попробовать

    local csums = assert(io.open('/tmp/checksums', 'w'))
    for cs in pairs(checksums) do csums:write(cs, '\n') end
    csums:close()
    

    А затем снова считайте контрольные суммы из файла, используя io.lines снова.

Надеюсь, этого достаточно, чтобы вы начали. Вы можете скачать Lua с http://lua.org,, и я рекомендую превосходную книгу Программирование на Lua (ознакомьтесь с предыдущим выпуском бесплатно онлайн ).

...