Подтвердить что ты не робот

Как я могу исключить несколько папок с помощью Get-ChildItem -exclude?

Мне нужно создать файл конфигурации для нашей системы CAD/Pro. Мне нужен рекурсивный список папок с определенного диска на нашем сервере. Однако мне нужно ИСКЛЮЧИТЬ любую папку с "АРХИВОМ" в ней, включая различные различные случаи.

Я написал следующее, которое работает, за исключением того, что оно не исключает папки!

$folder = "T:\Drawings\Design\*"
$raw_txt = "T:\Design Projects\Design_Admin\PowerShell\raw.txt"
$search_pro = "T:\Design Projects\Design_Admin\PowerShell\search.pro"
$archive = *archive*,*Archive*,*ARCHIVE*

Get-ChildItem -Path $folder -Exclude $archive -Recurse  | where {$_.Attributes -match 'Directory'}  | ForEach-Object {$_.FullName} > $search_pro   
4b9b3361

Ответ 1

Я бы сделал это вот так:

Get-ChildItem -Path $folder -r  | 
          ? { $_.PsIsContainer -and $_.FullName -notmatch 'archive' }

Ответ 2

Извиняюсь, если этот ответ кажется дублированием предыдущих ответов. Я просто хотел показать обновленный (проверенный через POSH 5.0) способ решения этого. Предыдущие ответы были до-3.0 и не столь эффективны, как современные решения.

Документация не понятна, но Get-ChildItem -Recurse -Exclude соответствует только исключению на листе (Split-Path $_.FullName -Leaf), а не родительскому path (Split-Path $_.FullName -Parent). Соответствие исключению просто удалит элемент с соответствующим листом; Get-ChildItem все равно будет возвращаться в этот лист.

В POSH 1.0 или 2.0

Get-ChildItem -Path $folder -Recurse  | 
          ? { $_.PsIsContainer -and $_.FullName -inotmatch 'archive' }

Примечание: Тот же ответьте как @CB.

В POSH 3.0 +

Get-ChildItem -Path $folder -Directory -Recurse  | 
          ? { $_.FullName -inotmatch 'archive' }

Примечание: Обновлено ответ от @CB.

Несколько исключений

Это специально предназначает каталоги, исключая листья с параметром Exclude, а родителям - сравнение ilike (без учета регистра):

#Requires -Version 3.0
[string[]]$Paths = @('C:\Temp', 'D:\Temp')
[string[]]$Excludes = @('*archive*', '*Archive*', '*ARCHIVE*', '*archival*')

$files = Get-ChildItem $Paths -Directory -Recurse -Exclude $Excludes | %{ 
    $allowed = $true
    foreach ($exclude in $Excludes) { 
        if ((Split-Path $_.FullName -Parent) -ilike $exclude) { 
            $allowed = $false
            break
        }
    }
    if ($allowed) {
        $_
    }
}

Примечание. Если вы хотите, чтобы ваш $Excludes был чувствительным к регистру, есть два шага:

  • Удалите параметр Exclude из Get-ChildItem.
  • Измените первое условие if на:
    • if ($_.FullName -clike $exclude) {

Примечание: Этот код имеет избыточность, которую я бы никогда не реализовал на производстве. Вы должны это упростить, чтобы соответствовать вашим конкретным потребностям. Он служит хорошим примером.

Ответ 3

Мой подход KISS для пропуска некоторых папок - это цепочка вызовов Get-ChildItem. Это исключает папки корневого уровня, но не папки более глубокого уровня, если вы этого хотите.

Get-ChildItem -Exclude folder1,folder2 | Get-ChildItem -Recurse | ...
  • Запустите исключая папки, которые вам не нужны
  • Затем выполните рекурсивный поиск, исключив ненужные папки.

Что мне нравится в этом подходе, так это то, что его легко запомнить. Если вы не хотите смешивать папки и файлы при первом поиске, вам понадобится фильтр.

Ответ 4

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

Тем не менее, параметр -Exclude принимает массив строк, поэтому, пока вы определяете $archive как таковой, вы должны быть установлены.

$archive = ("*archive*","*Archive*","*ARCHIVE*");

Вы также должны оставить конечную звездочку из $folder - поскольку вы указываете -recurse, вам нужно только указать папку верхнего уровня.

$folder = "T:\Drawings\Design\"

Полностью изменен script. Это также изменяет то, как вы обнаруживаете, находили ли вы каталог, и пропускаете Foreach-Object, потому что вы можете просто вытащить свойство напрямую и выгрузить все его в файл.

$folder = "T:\Drawings\Design\";
$raw_txt = "T:\Design Projects\Design_Admin\PowerShell\raw.txt";
$search_pro = "T:\Design Projects\Design_Admin\PowerShell\search.pro";
$archive = ("*archive*","*Archive*","*ARCHIVE*");

Get-ChildItem -Path $folder -Exclude $archive -Recurse  | where {$_.PSIsContainer}  | select-Object -expandproperty FullName |out-file $search_pro 

Ответ 5

Я знаю, что это довольно старый - но, пытаясь найти легкое решение, я наткнулся на эту тему... Если я правильно задал вопрос, вы искали способ перечислить несколько каталогов с помощью Get-ChildItem. Кажется, что намного проще использовать powershell 5.0 - пример

Get-ChildItem -Path D:\ -Directory -Name -Exclude tmp,music
   chaos
   docs
   downloads
   games
   pics
   videos

Без предложения -Exclude tmp и music все равно будут в этом списке. Если вы не используете -Name, предложение -Exclude не будет работать из-за подробного вывода Get-ChildItem. Надеюсь, это поможет некоторым людям, которые ищут простой способ перечислить все имена каталогов без определенных...

Приветствия лил

Ответ 6

VertigoRay в своем ответе объяснил, что -Exclude работает только на листовом уровне пути (для файла имя файла с удаленным путем; для подкаталога имя каталога с удаленным путем). Таким образом, похоже, что -Exclude нельзя использовать для указания каталога (например, "bin") и исключения всех файлов и подкаталогов в этом каталоге.

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

$rootFolderPath = 'C:\Temp\Test'
$excludeDirectories = ("bin", "obj");

function Exclude-Directories
{
    process
    {
        $allowThrough = $true
        foreach ($directoryToExclude in $excludeDirectories)
        {
            $directoryText = "*\" + $directoryToExclude
            $childText = "*\" + $directoryToExclude + "\*"
            if (($_.FullName -Like $directoryText -And $_.PsIsContainer) '
                -Or $_.FullName -Like $childText)
            {
                $allowThrough = $false
                break
            }
        }
        if ($allowThrough)
        {
            return $_
        }
    }
}

Clear-Host

Get-ChildItem $rootFolderPath -Recurse '
    | Exclude-Directories

Для дерева каталогов:

C:\Temp\Test\
|
├╴SomeFolder\
|  |
|  └╴bin (file without extension)
|
└╴MyApplication\
  |
  ├╴BinFile.txt
  ├╴FileA.txt
  ├╴FileB.txt
  |
  └╴bin\
    |
    └╴Debug\
      |
      └╴SomeFile.txt

Результат:

C:\Temp\Test\
|
├╴SomeFolder\
|  |
|  └╴bin (file without extension)
|
└╴MyApplication\
  |
  ├╴BinFile.txt
  ├╴FileA.txt
  └╴FileB.txt

Он исключает подпапку bin\и все ее содержимое, но не исключает файлы Bin.txt или bin (файл с именем "bin" без расширения).

Ответ 7

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

$exclude = 'dir1|dir2|dir3'
ls -r | where { $_.fullname -notmatch $exclude }

ls -r -dir | where fullname -notmatch 'dir1|dir2|dir3'

Ответ 8

может быть в вашем случае, вы можете достичь этого со следующим:

    mv excluded_dir ..\
    ls -R 
    mv ..\excluded_dir .