Ответ 1
Я бы сделал это вот так:
Get-ChildItem -Path $folder -r |
? { $_.PsIsContainer -and $_.FullName -notmatch 'archive' }
Мне нужно создать файл конфигурации для нашей системы 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
Я бы сделал это вот так:
Get-ChildItem -Path $folder -r |
? { $_.PsIsContainer -and $_.FullName -notmatch 'archive' }
Извиняюсь, если этот ответ кажется дублированием предыдущих ответов. Я просто хотел показать обновленный (проверенный через POSH 5.0) способ решения этого. Предыдущие ответы были до-3.0 и не столь эффективны, как современные решения.
Документация не понятна, но Get-ChildItem -Recurse -Exclude
соответствует только исключению на листе (Split-Path $_.FullName -Leaf
), а не родительскому path (Split-Path $_.FullName -Parent
). Соответствие исключению просто удалит элемент с соответствующим листом; Get-ChildItem
все равно будет возвращаться в этот лист.
Get-ChildItem -Path $folder -Recurse |
? { $_.PsIsContainer -and $_.FullName -inotmatch 'archive' }
Примечание: Тот же ответьте как @CB.
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) {
Примечание: Этот код имеет избыточность, которую я бы никогда не реализовал на производстве. Вы должны это упростить, чтобы соответствовать вашим конкретным потребностям. Он служит хорошим примером.
Мой подход KISS для пропуска некоторых папок - это цепочка вызовов Get-ChildItem
. Это исключает папки корневого уровня, но не папки более глубокого уровня, если вы этого хотите.
Get-ChildItem -Exclude folder1,folder2 | Get-ChildItem -Recurse | ...
Что мне нравится в этом подходе, так это то, что его легко запомнить. Если вы не хотите смешивать папки и файлы при первом поиске, вам понадобится фильтр.
Шаблон исключения должен быть нечувствительным к регистру, поэтому вам не нужно указывать каждый случай исключения.
Тем не менее, параметр -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
Я знаю, что это довольно старый - но, пытаясь найти легкое решение, я наткнулся на эту тему... Если я правильно задал вопрос, вы искали способ перечислить несколько каталогов с помощью 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. Надеюсь, это поможет некоторым людям, которые ищут простой способ перечислить все имена каталогов без определенных...
Приветствия лил
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" без расширения).
Вы можете исключить, например, символ "или" регулярного выражения, предполагая, что файл, который вы хотите, не имеет то же имя, что и выпадающая папка.
$exclude = 'dir1|dir2|dir3'
ls -r | where { $_.fullname -notmatch $exclude }
ls -r -dir | where fullname -notmatch 'dir1|dir2|dir3'
может быть в вашем случае, вы можете достичь этого со следующим:
mv excluded_dir ..\
ls -R
mv ..\excluded_dir .