识别包含图像的 .doc/.docx 文件

rev*_*rev 7 evernote docx images microsoft-word macos

我正在将我的笔​​记移至 Evernote。为此,我需要将 .doc/.docx 文件转换为 rtf。这样做的原因是我有一个脚本可以将 rtf 导入到印象笔记中。但是,我的一些 .doc/.docx 文件包含图像。

有没有办法识别哪些 .doc/.docx 文件包含图像而不查看它们?我有几千。通过这种方式,我可以简单地打开少数有图像的内容,然后将整个内容直接复制/粘贴到 Evernote 中。

应该说我使用的是 OS X 10.6.8。

slh*_*hck 11

.doc 文件在哪里存储图像?

Worddoc文件实际上被压缩,然后放入容器格式。它们以这种编译后的文件格式将媒体存储在某处,可能就在doc格式的标题之后。在图像数据之后,您的真实文档是一个 zip 兼容文件夹。

文件布局

因此,当您尝试解压缩doc文件时,会在开头获得过多的字节数。这些是您的图像(加上格式标题)。您现在可以尝试访问unzip该文件并检查多余的字节数。

charon:test werner$ unzip -c images.doc > /dev/null
warning [images.doc]:  47166 extra bytes at beginning or within zipfile

charon:test werner$ unzip -c noimages.doc > /dev/null
warning [noimages2.doc]:  6060 extra bytes at beginning or within zipfile
Run Code Online (Sandbox Code Playgroud)

通过测试,我发现“纯文本”Word 文档的标题有 6060 字节大(虽然有些大一点)。我们可以尝试利用它来确定文档中是否有图像。我们只说 8000 字节——因为真实图像肯定会超过几 KB。


.docx 文件呢?

使用 Office 2007 格式 ( docx),这要容易得多。这些是实际的压缩文件,任何包含任何类型(图像、视频)嵌入媒体的 Word 文件都将包含该file.docx/word/media目录。因此,我们只需要解压缩docx文件并检查该目录是否存在。


检查图像的脚本

  • 创建一个新的空文件,命名为docx-images.rb,然后粘贴以下内容:

    #!/usr/bin/env ruby
    require 'open3'
    TEMPDIR = "/tmp/word/"
    
    # check for docx files
    Dir.glob("**/*.docx").each do |file|
      system("rm -rf '#{TEMPDIR}'")
      system("unzip '#{file}' -d #{TEMPDIR} > /dev/null")
      if File.directory?("#{TEMPDIR}/word/media/")
        puts file
      end
    end
    
    # check for doc files
    Dir.glob("**/*.doc").each do |file|
      stdin, stdout, stderr = Open3.popen3("unzip -c '#{file}' > /dev/null")
      info = stderr.readlines[0]
      info = info.gsub(" extra bytes at beginning or within zipfile", "").gsub(/warning\s\[.*\]:\s+/, "")
      if info.to_i > 8000 # assume a little more than usual header size
        puts file
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)
  • 将它保存在某个地方,最好是在您要从中开始搜索docx文件的Documents文件夹中,可能是您的文件夹。

  • 现在,打开Terminal.app,然后使用cd ~/Documents它去那里。

  • 类型ruby docx-images.rb,并且它会递归扫描您的Documents文件夹docxdoc文件。它会将前者解压缩到/tmp/word,并检查它们是否包含嵌入式媒体。后者只是解压到/dev/null,因此不会留下任何痕迹。

  • 您最终会得到一个包含嵌入式媒体的列表。


证明

为了证明这是有效的,我创建了四个文件。一张有图片,一张没有图片——既是作为docdocx

证明

然后,运行脚本:

charon:test werner$ ruby docx-images.rb 
images.docx
images.doc
Run Code Online (Sandbox Code Playgroud)

显然,可以改进脚本以检查该media文件夹中的实际图像,但除非文件确实包含任何媒体,否则它不太可能存在。“6060”字节检查也是如此。这是一个黑客,但它对我有用。

当然,脚本取决于unzip各自系统上的实现,但它适用于 OS X 版本。