Найти все файлы .txt на ПК, исключая несколько путей в Powershell - PullRequest
0 голосов
/ 17 октября 2018

Я хочу найти все .txt файлы во всех разделах, но я не хочу смотреть в такие папки, как C: \ Windows, C: \ PerfLogs и т. Д. *

Мой код не 't работа.

$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;}}

Пожалуйста, сделайте мой код ресурсоэффективным.Заставьте его полностью пропустить исключенные папки, даже не возвращаясь в них.

Что странно, если я запускаю его только с одним элементом, и он все еще не работает.

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: \, он игнорирует исключение.

Я пробовал с подстановочными знаками вокруг слова Windows и без них, все тот же результат.

Также пробовал Где -NotContains, -NotIn ....

Пожалуйста, выполните команду самостоятельно и убедитесь сами

Ответы [ 3 ]

0 голосов
/ 17 октября 2018

Операторы -like и -notlike поддерживают только шаблон одиночный в качестве RHS, а не массив [1] , поэтому $_.FullName -notlike $exl не будет работать так, как вы ожидаете.
(Он преобразует массив $exl в одну строку, объединяя элементы массива с одним пробелом в качестве разделителя).

Youвместо этого можно использовать оператор 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] На GitHub существует давний, но томный запрос к функции, чтобы сделать -like / -notlike работать с массивами шаблонов тоже.

0 голосов
/ 17 октября 2018

Несколько наблюдений:

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

попробуйте использовать стандартную опцию для фильтрации (filter / exclude / include)

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

Хотя не уверены, есть ли встроенные опции фильтрации или гдеОператор ускорит выполнение, я думаю, что он будет сканировать все файлы в любом случае.Вы можете попытаться зациклить папки (вместо рекурсивного поиска) и пропустить их, чтобы избежать сканирования файлов в них.

0 голосов
/ 17 октября 2018

Я не уверен на 100%, если это проблема, но если я вспоминаю, что запятая создает массив может в PowerShell.

, Оператор запятой

Как бинарный оператор,запятая создает массив.Как унарный оператор, запятая создает массив с одним членом.Поставьте запятую перед членом.

Источник: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-6


В целях устранения неполадок вы можете просто попробовать один каталог, без запятых в переменной $ exl?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...