Powershell 如何查找文件夹中名称包含列表中单词的所有文件?

Powershell 如何查找文件夹中名称包含列表中单词的所有文件?,powershell,Powershell,我有一个巨大的文件列表,其名称包含一个数字。 另一方面,我有一个数字列表。 我需要使用PowerShell(或任何其他Windows资源)查找名称中包含其他列表中任何数字的文件列表 我知道如何使用 getchilditem | Where对象{$\类似于“*123*”的.Name} 但是我不知道如何在不使用-或操作符的情况下按整个列表进行搜索。试试以下方法: $files = ( Get-ChildItem 'path' ) $numbers = 1 .. 100 # or your list

我有一个巨大的文件列表,其名称包含一个数字。 另一方面,我有一个数字列表。 我需要使用PowerShell(或任何其他Windows资源)查找名称中包含其他列表中任何数字的文件列表

我知道如何使用

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