【问题标题】:Search MS word files in a directory for specific content in Linux在Linux中搜索目录中的MS word文件以获取特定内容
【发布时间】:2012-07-12 19:32:26
【问题描述】:

我有一个充满 MS Word 文件的目录结构,我必须在目录中搜索特定字符串。到目前为止,我一直在使用以下命令在目录中搜索文件

找到 . -exec grep -li 'search_string' {} \;

找到 . -name '*' -打印 | xargs grep 'search_string'

但是,此搜索不适用于 MS word 文件。

是否可以在 Linux 的 MS word 文件中进行字符串搜索?

【问题讨论】:

  • 要明确,哪个版本的 Word?从 Office 2003 到 Office 2007,文件格式发生了显着变化。
  • @DanielDiPaolo 我检查了文件类型,上面写着“Microsoft Office Word 97 - 2003 Document”

标签: linux unix ms-word


【解决方案1】:

我是一名翻译,对脚本编写几乎一无所知,但我对 grep 无法扫描 Word .doc 文件感到非常恼火,因此我想出了如何制作这个小 shell 脚本来使用 catdoc 和 grep在 .doc 文件目录中搜索给定的输入字符串。

你需要安装catdocdocx2txt

#!/bin/bash
echo -e "\n
Welcome to scandocs. This will search .doc AND .docx files in this directory for a given string. \n
Type in the text string you want to find... \n"
read response
find . -name "*.doc" | 
while read i; do catdoc "$i" | 
grep --color=auto -iH --label="$i" "$response"; done
find . -name "*.docx" | 
while read i; do docx2txt < "$i" | 
grep --color=auto -iH --label="$i" "$response"; done

欢迎所有改进和建议!

【讨论】:

  • 这令人印象深刻。所以我可以搜索多个子文件夹和文件夹并查看 .doc 内部 - 不过我也会检查 .docx ..
  • 我使用 docx2txt 添加了对 docx 的支持
  • 自 2020 年 1 月起可与 LibreOffice doc 和 docx 一起使用。
  • 如果您使用的是 UNIX,textutil 可以将 .doc.docx 都转换为文本。例如,textutil -stdout -cat txt theFile
【解决方案2】:

这是一种使用“解压缩”将整个内容打印到标准输出的方法,然后通过管道传输到“grep -q”以检测输出中是否存在所需的字符串。它适用于 docx 格式的文件。

#!/bin/bash
PROG=`basename $0`

if [ $# -eq 0 ]
then
  echo "Usage: $PROG string file.docx [file.docx...]"
  exit 1
fi

findme="$1"
shift

for file in $@
do
  unzip -p "$file" | grep -q "$findme"
  [ $? -eq 0 ] && echo "$file"
done

将脚本保存为“inword”并在三个文件中搜索“wombat”:

$ ./inword wombat file1.docx file2.docx file3.docx
file2.docx

现在您知道 file2.docx 包含“wombat”。您可以通过添加对其他 grep 选项的支持来获得更好的体验。玩得开心。

【讨论】:

    【解决方案3】:

    最新版本的 MS Word 将 ascii[0] 散布在文本的每个字母之间,用于我尚无法理解的目的。我编写了自己的 MS Word 搜索实用程序,在搜索字段中的每个字符之间插入 ascii[0],它工作得很好。笨拙但还可以。还有很多问题。也许垃圾字符并不总是相同的。需要做更多的测试。如果有人可以编写一个将所有这些考虑在内的实用程序,那就太好了。在我的 Windows 机器上,相同的文件对搜索响应良好。 我们可以做到这一点!

    【讨论】:

    • 我怀疑他们使用的是 UCS-2,因为很多 MS 产品在一段时间前都升级到了 UCS-2……只是为了 UTF-8 成为字符中最新最流行的趋势编码。
    【解决方案4】:

    .doc 文件中,文本通常存在并且可以通过 grep 找到,但是该文本被分解并散布有域代码和格式信息,因此搜索您知道的短语可能不匹配。搜索非常短的内容更有可能匹配。

    .docx 文件实际上是一个zip 存档,在一个目录结构中收集了多个文件(尝试将 .docx 重命名为 .zip 然后解压缩它!)- 使用 zip 压缩,grep 不太可能在全部。

    【讨论】:

    • @Stephen P 它是一个 .doc 文件,任何超过 3 个字符的搜索都不起作用。
    • @JoshMachine - 作为测试,您可能想在其中一个上尝试vim -bnR somefile.doc 以查看其中的内容,然后尝试使用 grep 查找您在文件中看到的内容。
    • 不知道.docx,有时间试试这个。
    【解决方案5】:

    开源命令行实用程序crgrep 将搜索大多数 MS 文档格式(我是作者)。

    【讨论】:

      【解决方案6】:

      你试过 awk '/Some|Word|In|Word/' document.docx 吗?

      【讨论】:

      • 诀窍是首先提取 doc 文件(其中包含 document.xml)然后 grep/awk
      【解决方案7】:

      如果文件不多,您可以编写一个包含 catdoc: http://manpages.ubuntu.com/manpages/gutsy/man1/catdoc.1.html 之类的脚本,方法是遍历每个文件,执行 catdoc 和 grep,将其存储在 bash 变量中,如果满意则将其输出。

      【讨论】:

        【解决方案8】:

        如果你安装了名为antiword的程序,你可以使用这个命令:

        find -iname "*.doc" |xargs -I {} bash -c 'if (antiword {}|grep "string_to_search") > /dev/null 2>&1; then echo {} ; fi'
        

        将上述命令中的“string_to_search”替换为您的文本。此命令吐出包含“string_to_search”的文件的文件名

        该命令并不完美,因为它在小文件上的工作很奇怪(结果可能是不可信),因为某些反义词会吐出以下文本:

        “我担心这个文件的文本流太小,无法处理。”

        如果文件很小(不管它是什么意思 .o.)

        【讨论】:

        【解决方案9】:

        我遇到的最佳解决方案是使用unoconv 将word 文档转换为html。它也有一个 .txt 输出,但在我的情况下它删除了内容。

        http://linux.die.net/man/1/unoconv

        【讨论】:

          【解决方案10】:

          我找到了一种使用 ripgrep 预处理器功能搜索 Word 文件(docdocx)的方法。

          这取决于正在安装的以下内容:

          • ripgrep(有关预处理器的更多信息here
          • LibreOffice
          • docx2txt
          • 这个 catdoc2 脚本,我已添加到我的$PATH
          #!/bin/bash
          
          temp_dir=$(mktemp -d)
          trap "rm $temp_dir/* && rmdir $temp_dir" 0 2 3 15
          
          libreoffice --headless --convert-to "txt:Text (encoded):UTF8" --outdir ${temp_dir} $1 1>/dev/null
          cat ${temp_dir}/$(basename -s .doc $1).txt
          

          一级递归搜索的命令模式是:

          $ rg --pre <preprocessor> --glob <glob with filetype> <search string> 
          

          例子:

          $ ls *
          one:
          a.docx
          
          two:
          b.docx  c.doc
          $ rg --pre docx2txt --glob *.docx This
          two/b.docx
          1:This is file b.
          
          one/a.docx
          1:This is file a.
          $ rg --pre catdoc2 --glob *.doc This
          two/c.doc
          1:This is file c.
          

          【讨论】:

            猜你喜欢
            • 2011-07-08
            • 1970-01-01
            • 2013-05-31
            • 1970-01-01
            • 1970-01-01
            • 2016-08-12
            • 1970-01-01
            • 2014-01-31
            • 2022-11-17
            相关资源
            最近更新 更多