Powershell 如何查找文件夹中名称包含列表中单词的所有文件?
我有一个巨大的文件列表,其名称包含一个数字。 另一方面,我有一个数字列表。 我需要使用PowerShell(或任何其他Windows资源)查找名称中包含其他列表中任何数字的文件列表 我知道如何使用Powershell 如何查找文件夹中名称包含列表中单词的所有文件?,powershell,Powershell,我有一个巨大的文件列表,其名称包含一个数字。 另一方面,我有一个数字列表。 我需要使用PowerShell(或任何其他Windows资源)查找名称中包含其他列表中任何数字的文件列表 我知道如何使用 getchilditem | Where对象{$\类似于“*123*”的.Name} 但是我不知道如何在不使用-或操作符的情况下按整个列表进行搜索。试试以下方法: $files = ( Get-ChildItem 'path' ) $numbers = 1 .. 100 # or your list
getchilditem | Where对象{$\类似于“*123*”的.Name}
但是我不知道如何在不使用-或操作符的情况下按整个列表进行搜索。试试以下方法:
$files = ( Get-ChildItem 'path' )
$numbers = 1 .. 100 # or your list contents
foreach( $n in $numbers ) {
foreach( $f in $files.BaseName ) {
if( $f -like "*$n*" ) {
"Found $f"
}
}
}
一种有效的方法是使用基于正则表达式的-match
,以及交替(|
)在单个操作中搜索多个模式之一:
$numbers = 42, 43, 44 # ...
Get-ChildItem | Where-Object Name -match ($numbers -join '|')
或者,显示您可以直接使用Get ChildItem
的(隐含的)-Path
参数(其类型为[string[]]
,即路径数组),以及通配符表达式数组:
$numbers = 42, 43, 44 # ...
Get-ChildItem ($numbers -replace '^|$', '*')
上面使用括号将每个数字括在*…*
中;也就是说,上述内容相当于:
Get-ChildItem *42*, *43*, *44*
文件中的模式:
get-childitem -name | select-string (get-content patterns.txt)
和一样,我们可以利用-Path
参数中的字符串数组进行过滤。这些都是很好的快速优雅的解决方案,对于有限的字符串集来说是很好的解决方案
当他提到他有数百个数字要匹配时,这种怪癖就出现了。当我们处理数百个名称以匹配数百个文件名时,这些方法都会以指数级的速度变慢。e、 g.证明了这一点。例如,当您有100个数字和1000个文件时,您将执行100 x 1000=100000次评估。我假设Get ChildItem
的内部代码在处理输入上的string[]
数组时会执行类似的操作
如果我们对纯性能感兴趣,我们就不能使用阵列。数组对于存储项目和访问索引位置非常有效,但对于随机查询来说却非常糟糕。我们可以使用一个稍微复杂一点的方法,使用Regex和。尽管哈希表是一个键/值系统,在本例中我们不需要“值”,但它们在查找、匹配和查询大量键时非常高效,通常成功率为“O(1)”。e、 我们的例子从一个O(n*f)问题到一个O(n)问题,我们只评估1 x 1000=1000次评估
首先,我们需要我们的密钥列表:
$FileWithListOfNumbers = @"
123 = Matched file with 123
456 = Matched file with 456
789 = Matched file with 789
"@
$KeyHashtable = ConvertFrom-StringData $FileWithListOfNumbers
这将用键列表加载哈希表。接下来,我们遍历文件并使用正则表达式匹配文件名:
Get-ChildItem | % {
if($_.Name -match '\D*(\d+)\D*')
{
#Filename contains a number, perform a key lookup to see if it matches
if($KeyHashtable.ContainsKey($Matches[1]))
{
Write-Host $_.Name
}
}
}
通过使用Regex进行匹配(而不是使用文件系统提供程序进行筛选),我们可以使用匹配组来“提取”数字。您可能需要根据您的特定需要和文件命名约定调整正则表达式,但它是:
-match '\D*(\d+)\D*'
\D* - Match 0 or more non-digits
( - Start of capture group
\d+ - Match 1 or more digits
) - End of capture group
\D* - Match 0 or more non-digits
我们“提取”的数字存储在第二个数组位置的特殊$Matches
变量$Matches[1]
中。然后,我们使用该数字执行密钥查找,以查看它是否与我们正在查找的任何内容匹配。在下面的评论中,您指出,“我的搜索列表有数百个数字,因此即使手动搜索也会很痛苦。”-请将此要求(不希望单独列举数字)添加到您的问题中,以更明确地说明。
-match '\D*(\d+)\D*'
\D* - Match 0 or more non-digits
( - Start of capture group
\d+ - Match 1 or more digits
) - End of capture group
\D* - Match 0 or more non-digits