我有一个名为“ SFO104”的项目,并且有一个序列号列表,即5011849、5011850等,我必须搜索一长串包含500多个序列号的列表,以查看它们是否存在于与以下内容无关的任何其他文档中项目名称 SFO104 或PO编号 114786 。
我当时想将搜索到的每个序列号的搜索结果输出到csv中,但以下方法不起作用。
$searchWords = gc C:\Users\david.craven\Documents\list.txt
$results = @()
Foreach ($sw in $searchWords)
{
$files = gci -path C:\Users\david.craven\Dropbox\ -filter "*$sw*" -recurse | select FullName
foreach ($file in $files)
{
$object = New-Object System.Object
$object | Add-Member -Type NoteProperty –Name SearchWord –Value $sw
$object | Add-Member -Type NoteProperty –Name FoundFile –Value $file
$results += $object
}
}
$results | Export-Csv C:\Users\david.craven\Documents\results.csv -NoTypeInformation
下图显示了我对序列号 5011849 的搜索,返回的结果与项目 SFO104 相符,符合预期。
答案 0 :(得分:2)
您的代码有效,文件已填充。但是,您指定的标题没有如屏幕快照中定义的标题。另外,该list.txt是什么样的。我的searchlist.txt是一个单列文件:
Hello
client
照原样使用代码,仅更改文件路径和名称,并稍加修改文件名的访问位置,即可得到这些结果...
$searchWords = gc 'D:\Scripts\searchlist.txt'
$results = @()
Foreach ($sw in $searchWords)
{
$files = gci -path d:\temp -filter "*$sw*" -recurse
foreach ($file in $files)
{
$object = New-Object System.Object
$object | Add-Member -Type NoteProperty –Name SearchWord –Value $sw
$object | Add-Member -Type NoteProperty –Name FoundFile –Value $file.FullName
$results += $object
}
}
$results | Export-Csv d:\temp\searchresults.csv -NoTypeInformation
# Results
# psEdit -filenames 'd:\temp\searchresults.csv'
SearchWord FoundFile
---------- ---------
Hello D:\temp\Duplicates\PowerShellOutput.txt
Hello D:\temp\Duplicates\BeforeRename1\PowerShellOutput.txt
Hello D:\temp\Duplicates\PoSH\PowerShellOutput.txt
Hello D:\temp\Duplicates\Text\PowerShellOutput.txt
client D:\temp\Client.txt
client D:\temp\Duplicates\CertLabClients_v1.ps1
client D:\temp\Duplicates\Check Logon Server for Client.ps1
client D:\temp\Duplicates\Create Wireless Hosted Networks in Windows Clients.ps1
...
OP更新
由于您使用的是逗号分隔的列表。您需要将其分解为单独的项目。我将文件更改为此
Hello,client
除非尝试匹配整个连续字符串,否则无法在该布局上进行匹配。所以,如果我这样打破上面的话...
$searchWords = (gc 'D:\Scripts\searchlist.txt') -split ','
…因此结果如前所示。
OP的更新
示例,使用此方法(不同的粗略方法)进行测试...
Foreach ($sw in $searchWords)
{
Get-Childitem -Path "d:\temp" -Recurse -include "*.txt","*.csv" |
Select-String -Pattern "$sw" |
Select Path,LineNumber,@{n='SearchWord';e={$sw}}
}
添加了LineNumber,因此请显示字符串所在的位置。另外,请注意,您的代码以及我在此处提供的内容仅适用于文本,csv文件。
如果计划打doc,docx,xls,xlsx,则意味着需要更多代码,因为您必须使用默认应用程序Word,Excel打开和读取这些文件。
这意味着对代码中的每种文件类型都使用COM对象模型。如此处讨论和显示的:
How do I make powershell search a Word document for wildcards and return the word it found?
您需要为Excel或PowerPoint做类似的事情,如果您有PDF,则需要添加附件。
OP更新
就像我说的那样,我很快将它们放在一起,所以我确实使用输入文件和目标文件夹树对其进行了测试,因此有点粗糙(没有错误处理等)。
# This is what my input looks like
Hello,client
595959, 464646
LIC
运行代码应该仅使用 .txt和 .csv文件为您提供以下结果。按照我上面的评论,使用任何其他文件类型都会因设计原因而出错,如果不将本机应用程序用于非文本文件类型,则不能对非基于文本的文件使用此方法。
$searchWords = ((gc 'D:\Scripts\searchlist.txt') -split ',').Trim()
Foreach ($sw in $searchWords)
{
Get-Childitem -Path "d:\temp" -Recurse -include "*.txt","*.csv" |
Select-String -Pattern "$sw" |
Select Path,LineNumber,@{n='SearchWord';e={$sw}}
}
Path LineNumber SearchWord
---- ---------- ----------
D:\temp\Duplicates\BeforeRename1\PsGet.txt 157 Hello
...
D:\temp\Duplicates\PoSH\PsGet.txt 157 Hello
...
D:\temp\Duplicates\BeforeRename1\PoSH-Get-Mo... 108 client
D:\temp\Duplicates\BeforeRename1\Powershell ... 12 client
D:\temp\Duplicates\BeforeRename1\Powershell ... 15 client
D:\temp\Duplicates\BeforeRename1\PsGet.txt 454 client
...
D:\temp\newfile.txt 4 client
D:\temp\MyFile.txt 5 595959
D:\temp\ProcessNames.csv 4 595959
D:\temp\Duplicates\Text\JSON-CSS.txt 30 464646
D:\temp\Duplicates\JSON-CSS.txt 30 464646
D:\temp\MyFile.txt 5 464646
D:\temp\ProcessNames.csv 4 464646
D:\temp\Duplicates\BeforeRename1\GetSetScree... 7 LIC