过滤文件夹列表数组时遇到问题

时间:2018-10-02 15:23:44

标签: powershell

我有一个文件夹名称列表,它超过一百万行,但是看起来像这样...

\\HOSTNAME\c$\Docs\PROD\10009991\BILLS\2018                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10009993\BILLS                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10009993\BILLS\2014                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10009993\BILLS\2015                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10009993\BILLS\2016                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10009995\BILLS                                                                                                                    
\\HOSTNAME\c$\Docs\PROD\10009995\BILLS\2014                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10009995\BILLS\2015                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10009996\BILLS                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10009996\BILLS\2014                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10009996\BILLS\2015                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10009996\BILLS\2016                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10009996\BILLS\2017                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10009996\BILLS\2018                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10010006\10006                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10010006\BILLS                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10010006\10006\BILLS                                                                                                                 
\\HOSTNAME\c$\Docs\PROD\10010006\10006\BILLS\2013                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010006\10006\BILLS\2015                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010006\10006\BILLS\2016                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010006\10006\BILLS\2017                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010006\10006\BILLS\2018                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010006\BILLS\2013                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10010006\BILLS\2015                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10010006\BILLS\2016                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10010006\BILLS\2017                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10010009\10009                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10010009\BILLS                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10010009\10009\BILLS                                                                                                                 
\\HOSTNAME\c$\Docs\PROD\10010011\10011                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10010011\BILLS                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10010011\10011\BILLS                                                                                                                 
\\HOSTNAME\c$\Docs\PROD\10010013\10013                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10010013\BILLS                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10010013\10013\BILLS                                                                                                                 
\\HOSTNAME\c$\Docs\PROD\10010013\10013\BILLS\2015                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010013\10013\BILLS\2016                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010013\10013\BILLS\2017                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010013\10013\BILLS\2018                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010013\BILLS\2015                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10010013\BILLS\2016                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10010013\BILLS\2017                                                                                                                  
\\HOSTNAME\c$\Docs\PROD\10010014\10014                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10010014\BILLS                                                                                                                       
\\HOSTNAME\c$\Docs\PROD\10010014\10014\BILLS                                                                                                                 
\\HOSTNAME\c$\Docs\PROD\10010014\10014\BILLS\2015                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010014\10014\BILLS\2016                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010014\10014\BILLS\2017                                                                                                            
\\HOSTNAME\c$\Docs\PROD\10010014\BILLS\2015 

基本上,我正在寻找少数在8位数字后没有BILLS文件夹的客户ID。

因此它应该返回此行,例如:

\HOSTNAME\c$\Docs\PROD\10010006\10006\BILLS

我知道会有很多重复。最终,我只想要列出旧帐号子文件夹的帐户列表。到目前为止,这是我目前无法使用的内容。它只是打印出整个列表。

$list = Get-Content "sample.txt"
foreach ($i in $list){
    $parts = $i -split '\\'
    if ($parts[7] -notlike '%Bills%'){
        Write-Host $parts
    }
}

4 个答案:

答案 0 :(得分:1)

所以我在其他地方找到了答案,避免了XKCD DenverCoder9模因...

我的问题是在Powershell中*是通配符,而不是%。

答案 1 :(得分:1)

根据您的上述数据

$list -split "`r?`n" | Select-String -Pattern '(?<=\\)\d{8}(?!\\BILLS)'|
  ForEach-Object {$_.Matches.Groups[0].Value} | 
    Sort-Object -Unique

返回:

10010006
10010009
10010011
10010013
10010014

通过使用带有nonconsuming positive look behind (?<=\\)
的正则表达式 负面的展望(?!\\BILLS)

答案 2 :(得分:0)

好的,所以您可以使用一些正则表达式。 目标是让所有没有Bills名称的行都以8位数字结尾

Get-Content "C:\Test\Fast Build\Bills_Test.txt" | ?{$_ -notmatch "[0-9]{8}.BILLS"}

让我们回顾一下这里发生的事情

我们获取内容,然后逐行将 | 输出到 Where-Object ,别名为< strong>?。然后,我们确保使用-notmatch运算符(在powershell中匹配检查aginst正则表达式,就像检查aginst通配符一样)。 在正则表达式中,我们正在寻找没有8位数字和 [0-9] {8} 以及通配符 BILLS 的所有内容。

答案 3 :(得分:0)

实际上,您的主要问题是错误地将%而不是* 用作字符匹配(包括无通配符)元字符的匹配。

但是,还有其他值得改进的地方

  • 对于大型文件,请勿使用$list = Get-Content "sample.txt"将行数组一次读入内存 -而是使用PowerShell的 pipeline 通过管道连接到ForEach-Object cmdlet来处理一个行。

  • 不要使用Write-Host输出结果;这样做只会写入控制台,而您将无法捕获数据以进行后续处理;而是使用Write-Output,或者最好使用隐式输出。

  • 您不一定需要与BILLS路径组成部分匹配的通配符-您需要的是从末端修剪尾部空格在与'BILLS'一起使用 literal 字符串比较之前。

将它们放在一起:

Get-Content sample.txt | ForEach-Object {
  $parts = $_ -split '\\'
  if ($parts[7].TrimEnd() -ne 'BILLS') { $parts[6] }
}

$parts[6]是帐号-请注意,通过不将其分配给变量或将其重定向到其他位置,它会隐式输出,因此循环仅根据请求返回帐号


以上内容可提高内存效率,但可能会变慢。 如果有问题,请直接使用.NET Framework阅读这些行。

[IO.File]::ReadLines("$PWD/sample.txt") | ForEach-Object {
  $parts = $_ -split '\\'
  if ($parts[7].TrimEnd() -ne 'BILLS') { $parts[6] }
}