在Linux中搜索目录中MS Word文件的特定内容

25
我有一个包含许多 MS Word 文件的目录结构,我需要在这个目录中查找特定字符串。到目前为止,我一直在使用以下命令在目录中搜索文件:

find . -exec grep -li 'search_string' {} \;

find . -name '*' -print | xargs grep 'search_string'

但是,这种搜索方法无法在 MS Word 文件中进行。

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


要明确一下,是哪个版本的Word?从Office 2003到Office 2007,文件格式有很大变化。 - Daniel DiPaolo
@DanielDiPaolo 我检查了文件类型,它显示为“Microsoft Office Word 97-2003文档”。 - JoshMachine
11个回答

36

我是一名翻译,对脚本编写一窍不通,但是我很生气grep不能扫描Word.doc文件的内容,所以我想出了这个小的shell脚本,使用catdoc和grep搜索一个目录中的.doc文件来查找给定的输入字符串。

您需要安装catdoc和docx2txt包。

#!/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

欢迎提出所有改进和建议!


3
相当令人印象深刻。所以我可以搜索多个子文件夹和文件夹并查看.doc文件 - 我还会检查.docx文件。 - TheBlackBenzKid
我使用docx2txt添加了对docx的支持。 - leszek.hanusz
截至2020年1月,它可以与LibreOffice的doc和docx格式文件一起使用。 - Reb.Cabin
5
如果您正在使用UNIX系统,textutil 可以将.doc.docx文件转换为文本。例如,textutil -stdout -cat txt theFile - colossatr0n

6
这里有一种使用“unzip”命令将整个文档内容打印到标准输出的方法,然后通过管道连接“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包含“袋熊”了。您可以添加其他grep选项支持,让它更加高级。玩得愉快。


4
最新版本的MS Word会在文本的每个字母之间插入ASCII[0]以用于某些目的,但我还不能理解其具体作用。我自己编写了MS Word搜索工具,在搜索字段的每个字符之间插入ASCII[0],它可以正常工作,虽然有些笨拙但还算可行。然而仍有很多问题需要解决,也许这些垃圾字符并不总是相同的,需要进行更多的测试。如果有人能编写一个能够考虑所有这些因素的实用程序就好了。在我的Windows机器上,同样的文件对搜索的响应很好。我们可以做到!

我怀疑他们正在使用UCS-2,因为许多微软产品在一段时间前被升级到了UCS-2...只是为了UTF-8成为最流行的字符编码趋势。 - Iiridayn

3
在一个 .doc 文件中,文本通常存在,并且可以通过 grep 找到,但是该文本被分解并与字段代码和格式信息混合在一起,因此搜索您知道存在的短语可能不匹配。搜索非常短的内容有更好的匹配机会。
.docx 文件实际上是一个 zip 归档文件,将几个文件收集在一个目录结构中(尝试将 .docx 重命名为 .zip 然后解压缩它!)-- 使用 zip 压缩,grep 很难找到任何东西。

这是一个.doc文件,任何超过3个字符的搜索都无法工作。 - JoshMachine
@JoshMachine - 作为一个测试,你可能想在其中之一上尝试 vim -bnR somefile.doc 来查看里面的内容,然后尝试使用 grep 查找你在文件中看到的东西。 - Stephen P
不知道关于 .docx 的这个,得有时间试一下。 - Hashim Aziz

1
开源命令行实用程序 crgrep 可以搜索大多数微软文档格式(我是作者)。

0
我找到的最佳解决方案是使用 unoconv 将 Word 文档转换为 HTML。它也可以输出 .txt 文件,但在我的情况下会丢失内容。

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


0

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

这取决于以下内容是否已安装:

  • ripgrep(有关预处理器的更多信息在此处
  • 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.

0
如果您已经安装了名为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" 的文件名。

该命令并不完美,因为对于小文件它的工作方式很奇怪(结果可能是不可靠的),因为由于某种原因 antiword 会输出以下文本:

"我很抱歉,这个文件的文本流太小了,无法处理。"

如果文件很小(无论它意味着什么 .o.)


由于 antiword 的限制,可能无法正确处理。也许这个链接 https://github.com/rainey/antiword-xp-rb/wiki 是解决方案(尽管我目前还没有使用过它)。 - xliiv

0

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


技巧在于首先提取doc文件(其中包含document.xml),然后使用grep/awk进行处理。 - Marjan Nikolovski

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接