在PC上查找所有.txt文件,同时在Powershell中排除多个路径

时间:2018-10-16 23:31:15

标签: powershell

我想在所有分区中找到所有.txt文件,但我不想在C:\ Windows,C:\ PerfLogs等文件夹中查找...

我的代码不起作用。

$exl = ("*\PerfLogs\*","*\Program Files*","*\ProgramData\*","*\Windows\*",":\Python*");

foreach($i in (Get-PSDrive).Name -match '^[a-z]$'){ 
        foreach($item in (Get-ChildItem "${i}:\*.txt" -Recurse | Where {$_.FullName -notlike $exl})) { 
                echo $item.Fullname;}}

请提高我的代码资源效率。使其完全跳过排除的文件夹,而无需递归到它们。

奇怪的是,我只用1个元素运行它,但它仍然无法正常工作。

foreach($i in (Get-PSDrive).Name -match '^[a-z]$'){ foreach($item in (Get-ChildItem "${i}:\*.txt" -Recurse | Where-Object {$_.FullName -NotLike "Windows"})) { echo $item.Fullname;}}

它仍然在C:\中打印所有txt文件,它会忽略该异常。

我尝试在 Windows 一词周围使用通配符,但没有通配符,结果仍然相同。

还尝试了-NotContains,-NotIn ....

请您自己运行命令并亲自查看

3 个答案:

答案 0 :(得分:3)

-like-notlike运算符仅支持模式作为RHS,不支持数组 < sup> [1] ,所以$_.FullName -notlike $exl不会按您期望的那样工作。
(它将通过使用单个空格作为分隔符来连接数组元素,从而将数组$exl转换为单个字符串。

您可以将switch语句与-wildcard选项一起使用:

$driveRoots = (Get-PSDrive -PSProvider FileSystem).Root
Get-ChildItem -Recurse $driveRoots -Filter *.txt | Where-Object {
  switch -wildcard ($_.FullName) {
    '*\PerfLogs\*'     { break }
    '*\Program Files*' { break }
    '*\ProgramData\*'  { break }
    ':\Python*'        { break }
    default            { return $True } # doesn't match exclusion -> include
  }
  return $False # matches exclusion -> exclude
}

尽管此解决方案不会阻止递归到与模式匹配的文件夹中,但使用-Filter参数通过使文件系统提供程序执行初始筛选可以大大减少扫描工作。


[1]长期存在但苦恼的feature request on GitHub也使-like / -notlike也可以处理模式数组。

答案 1 :(得分:0)

我不确定这是否是问题的100%,但如果我记得逗号在PowerShell中可以创建can数组。

,逗号运算符

作为二进制运算符,逗号创建一个数组。作为一元运算符,逗号创建一个包含一个成员的数组。将逗号放在成员之前。

来源:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-6


出于故障排除的目的,您可以只尝试1个目录,而$ exl变量中没有任何逗号吗?

答案 2 :(得分:0)

很少观察到

-NotLike "Windows"  #you forgot *, this will only be false when item name is "Windows"
-notlike $exl # not like with array will always return true

尝试使用标准选项进行过滤(过滤器/排除/包含)

$files = Get-ChildItem -Path '~'  -Recurse -file  -Include *.txt -Exclude *anac*, *bz*

尽管不确定是内置过滤器选项还是运算符可以加快执行速度,但我认为它仍然会扫描所有文件。您可以尝试仅循环浏览文件夹(而不是递归搜索),并跳过那些文件夹以避免在其中扫描文件。