【问题标题】:How do I make powershell search a Word document for wildcards and return the word it found?如何让 powershell 在 Word 文档中搜索通配符并返回它找到的单词?
【发布时间】:2016-10-04 22:11:35
【问题描述】:

我正在大量的 Word 文档 (5000) 中搜索大量的字符串 (3000)。我知道如何在 Powershell 脚本中执行此操作,但这需要很长时间。幸运的是,这些字符串中的大多数在前 3 或 4 个字符中都有共同的文本,如果在 find.execute 语句中使用通配符搜索,我可以将字符串缩小到大约 300 个。如果我在 strings.txt 中搜索 (cod)*,并在 Word 文档中找到诸如“code”、“coding”、“coded”等结果,我需要将这些结果放入文本文件中。但是,我的运气并不好。

$filePath = "C:\files\"
$textPath = "C:\strings.txt"
$outputPath = "C:\output.txt"
$findTexts = (Get-Content $textPath)
$docs = Get-childitem -path $filePath -Recurse -Include *.docx 
$application = New-Object -comobject word.application 
Foreach ($doc in $docs)
{
   $document = $application.documents.open("$doc", $false, $true)
   $application.visible = $False
   $matchCase = $false 
   $matchWholeWord = $false 
   $matchWildCards = $true 
   $matchSoundsLike = $false 
   $matchAllWordForms = $false 
   $forward = $true 
   $wrap = 1
   $range = $document.content
   $null = $range.movestart()

   Foreach ($findtext in $findTexts)
   {
       $wordFound = $range.find.execute($findText,$matchCase,$matchWholeWord,$matchWildCards,$matchSoundsLike, $matchAllWordForms,$forward,$wrap) 
       if ($wordFound) 
       { 
           $docName = $doc.Name
           #Output search results and file name to a tab-delimited file
           "$findText`t$docName" | Out-File -append $outputPath   
        } #end if $wordFound 

     } #end foreach $findText
$document.close()
} #end foreach $doc
$application.quit()

如果我有一个 Word 文档,其中包含单词“coding”,则此脚本会生成包含 (cod)* 通配符和文件名的 output.txt,因为 $findText = (cod)*.那么有没有办法让“编码”这个词输出到文件中呢?

【问题讨论】:

  • 你可能会发现OpenXML SDK会比Word.Application更快地解决这种类型的任务
  • 我已经考虑过了,但我的公司坚持不安装任何额外的东西,比如那个 SDK。如果这是唯一的解决方案,我会敦促他们破例,但我希望可能有一种利用 Word.Application 的方法。我确实尝试通过打开 Word 文档一次,然后在关闭它之前搜索 3000 个字符串来尽可能高效地运行它。它有所帮助,但仍然需要很长时间。
  • 如果有帮助,整个 SDK 包含在一个静态 dll + 一个 XML 清单中,无需在机器上安装或注册任何东西。
  • 感谢 Mathias,我能够获得它,所以除了 Dave 的正则表达式选项之外,这可能是另一个不错的选择。你知道它是怎么编码的吗?
  • 这实际上正是我对另一个问题的回答所做的:P(注意它在内部关键字循环中使用-match)。

标签: powershell


【解决方案1】:

不使用 Word 的通配符搜索,为什么不对文档中的所有文本使用 Powershell 正则表达式。像这样的:

if ($document.Content.Text -match "\b$($findText)\w+\b") 
{ 
  $docName = $doc.Name
  "$($matches[0])`t$docName" | Out-File -append $outputPath   
}

【讨论】:

  • 谢谢,戴夫。这非常有效。我最初坚持使用 Word 方法以只读方式打开文档,因为许多文档中可以包含 cmets,如果它没有以只读模式打开,它会停止并显示一个关于文档的对话框厘米。由于我使用 Word 方法打开它,我想我也会使用 Word 方法进行查找。但是您的解决方案结合了两者的优点,而且效果很好。谢谢!
  • 这很好用,但它似乎只返回找到的第一个匹配项。有没有办法让它列出所有匹配项?
猜你喜欢
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 2016-09-17
  • 2011-07-03
  • 2019-02-28
相关资源
最近更新 更多