用于将CD上的文件而不是硬盘上的文件复制到新目录的脚本

时间:2010-04-12 16:58:21

标签: windows scripting checksum file-management consolidation

我需要从一组CD中复制文件,这些CD中有很多重复的内容,彼此以及我的硬盘上已有的内容。相同文件的文件名不相同,并且位于不同名称的子目录中。我想将CD中的非重复文件复制到硬盘上的新目录中。我不关心子目录 - 我稍后会解决它 - 我只想要独特的文件。

我无法找到软件 - 请参阅我在SuperUser https://superuser.com/questions/129944/software-to-copy-non-duplicate-files-from-cd-dvd

的帖子

SuperUser的某个人建议我使用GNU的“find”和一些校验和工具的Win32版本来编写脚本。我瞥了一眼,之前没有做过那样的事情。我希望存在一些我可以修改的内容。

我找到了一个很好的程序来删除重复项,Duplicate Cleaner(它比较校验和),但它对我没有帮助,因为我必须将所有CD复制到磁盘,每个可能大约80%重复,我没有足够的空间去做那件事 - 我必须一次又一次地循环复制所有内容,然后转过来并删除80%的内容,对硬盘进行大量工作。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我不使用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从文件中读取校验和。

我希望这足以让你开始。您可以从http://lua.org下载Lua,我推荐一流的图书Programming in Lua(查看previous edition free online)。