你好,我的问题是有更快的方法来搜索select-string以外的文件中的短语。我需要在大约60k文件的第一行中找到某个短语,但我现在这样做的方式对于我需要做的事情来说太慢了。 我试过做
(Select-String "Phrase I am looking for" (cat mylist1)).Filename > mylist2
给了我2分30秒的结果,然后我尝试了
cat mylist1| %{ if ((cat $_ -first 1) -match "Phrase I am looking for") {echo $_}} > mylist2
给了我2分57秒的结果。是否有另一种通过大量文件搜索字符串的方法可以缩短搜索时间?
答案 0 :(得分:4)
由于您至少拥有PowerShell 3.0,因此您可以将.Where
与Get-Content
' s -TotalCount
一起使用,这对某些人有帮助。 -TotalCount
定义了正在读取的文件行数。我发现您已经在使用其别名-First
,因此此处不会有任何重大更改。
$path = "d:\temp"
$matchingPattern = "function"
(Get-ChildItem $path -File).Where{(Get-Content $_ -TotalCount 1) -match $matchingPattern }
我会尝试对60K的文件进行测试,看看我能在平均htim中得到什么。以上将返回第一行包含" function"的文件对象。我的测试是针对60K的文件,但我的线路可能更短。仍然在44秒内完成,所以也许会帮助你
StreamReader通常也会击败Get-Content
,但由于我们只获得一行,所以我认为它不会更有效率。这在where子句中使用streamreader并读取第一行。
(Get-ChildItem $path -File).Where{([System.IO.File]::OpenText($_.Fullname).ReadLine()) -match $matchingPattern }
请注意,上面的代码可能包含内存泄漏但与第一次测试相比,它在8秒内完成。写入文件添加了一两个。你的里程会有所不同。
请注意-match
支持正则表达式,因此如果存在,则需要转义正则表达式元字符。
答案 1 :(得分:1)
你可以做到这一点:
$yoursearch = "PowerShell is cool!"
get-content "c:\temp\*.*" -TotalCount 1 | where { $_ -ilike "*$yoursearch*"} | select PSPath, @{N="Founded";E={$_}}
或非纯粹主义者的简短版本:
gc "c:\temp\*.*" -To 1 | ? { $_ -ilike "*$yoursearch*"} | select PSPath, {$_}
如果要导出结果:
$yoursearch = "PowerShell is cool!"
get-content "c:\temp\*.*" -TotalCount 1 | where { $_ -ilike "*$yoursearch*"} | select PSPath, @{N="Founded";E={$_}} |
export-csv "c:\temp\yourresult.csv" -notype
如果您想要更好的文件输入过滤器:
Get-ChildItem "c:\temp" -File |
Where {$firstrow= (Get-Content $_.FullName -TotalCount 1); $firstrow -ilike "*$yoursearch*"} |
Select fullName, @{N="Founded";E={$firstrow}} |
Export-Csv "c:\temp\yourresult.csv" -notype
或非纯粹主义者的简短版本:
gci "c:\temp" -File | ? {$r= (gc $_.FullName -TotalCount 1); $r -ilike "*$yoursearch*"} |
Select f*, @{N="Founded";E={$r}} |
epcsv "c:\temp\yourresult.csv" -notype
注意:-file选项仅存在于PowerShell V5(或+)中,否则使用psiscontainer propertie进入where where
注2:您可以使用select-string的选项-list,在文件中搜索所有内容,但在创建1行时停止
$yoursearch = "PowerShell where are you"
Select-String -Path "c:\temp\*.*" -Pattern $yoursearch -list | select Path, Line | export-csv "C:\temp\result.csv" -NoTypeInformation
答案 2 :(得分:0)
写入文件的快捷方法是使用StreamWriter对象。假设文件位于文件夹中:
$writer = [System.IO.StreamWriter] "selection.txt"
$files = gci -Path $path
$pattern ="Phrase"
$files | %{gc -Path $_.FullName | select -First 1 | ?{$_ -match $pattern}} | %{$writer.WriteLine($_)}
答案 3 :(得分:0)
关于我将如何做的一个例子就像是
Get-ChildItem -Path $ path | Where-Object {$ _。Name -contains“My String”}
这通常是实现这一目标的一种非常快捷的方法,但是如果你 - 通过整个C:\驱动器进行检查,那么无论你是否会坐一分钟,除非你多线程