Как составить список содержимого совпадающих каталогов, независимо от того, содержит ли ввод строки Get-ChildItem символы подстановки или нет в PowerShelll - PullRequest
0 голосов
/ 06 ноября 2018

Я ищу способ для последовательного отображения содержимого каталога в следующем сценарии, т.е.

$dirs = @("C:/dir1", "C:/dir2", "C:/dir[3-5]")

foreach ($d in $dirs) {
  Get-ChildItem $d
}

Для первой и второй итераций перечисляется содержимое каталога, но для 3-й итерации перечисляются только соответствующие каталоги, а не их содержимое.

Пожалуйста, предоставьте для PowerShell v2 +

Ответы [ 3 ]

0 голосов
/ 06 ноября 2018

Используйте Get-ChildItem -LiteralPath $d вместо Get-ChildItem $d, поскольку первая переменная линии будет использоваться как -Path, что позволяет использовать подстановочные выражения. -LiteralPath $d нет.

$dirs = @("C:/dir1", "C:/dir2", "C:/dir[3-5]")

foreach ($d in $dirs) {
  Get-ChildItem -LiteralPath $d
}
0 голосов
/ 06 ноября 2018

Вы можете использовать Get-Item для выполнения подстановочного знака, а затем получать дочерние элементы каждого совпадения:

foreach ($dir in Get-Item $dirs) {
    Get-ChildItem -LiteralPath $dir
}
0 голосов
/ 06 ноября 2018

Примечание:

  • Полезный ответ Дона Круикшанка дает эффективное и элегантное решение.

  • Этот ответ предоставляет некоторую справочную информацию и предлагает альтернативное решение на основе Convert-Path.


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

Буквальный путь:

# NO wildcard -> directory *content* is listed
PS> Get-ChildItem C:\Windows

    Directory: C:\Windows


Mode                LastWriteTime         Length Name                                                                                                          
----                -------------         ------ ----                                                                                                          
d-----        4/11/2018   7:38 PM                addins                                                                                                        
d-----        8/16/2018  10:06 AM                appcompat                                                                                                     
d-----        10/9/2018   5:39 PM                apppatch                                                                                                      

Подстановочный путь (обратите внимание на [...] вокруг s):

# Wildcard -> resolved directory *itself* is listed
PS> Get-ChildItem C:\Window[s]


    Directory: C:\


Mode                LastWriteTime         Length Name                                                                                                          
----                -------------         ------ ----                                                                                                          
d-----        9/18/2018  10:07 PM                Windows                                                                                                       

Таким образом, для того, чтобы перечислить содержимое каталогов , подстановочные выражения должны быть разрешены в соответствующие им пути , перед тем, как передаст их Get-ChildItem.

Одним из вариантов является использование Convert-Path командлета first [1] и передача его вывода в Get-ChildItem через параметр -LiteralPath:

Get-ChildItem -LiteralPath ('C:/dir1', 'C:/dir2' + (Convert-Path 'C:/dir[3-5]'))

Примечание: использование -LiteralPath не является строго необходимым, но является хорошей практикой, поскольку указание путей позиционно - в качестве первого позиционного аргумента - неявно связывается с параметром -Path, который интерпретирует его аргументы в виде шаблонов подстановки , и существует риск случайного литерального пути , похожего на шаблонов подстановки.

Обратите внимание, как указанная выше команда передает все (результирующие) каталоги в виде массива в одиночный вызов Get-ChildItem, что делает команду более эффективной.

Однако в данном сценарии вам все равно может понадобиться использовать отдельные Get-ChildItem вызовы в цикле:

foreach ($dir in 'C:/dir1', 'C:/dir2' + (Convert-Path 'C:/dir[3-5]')) {
   Get-ChildItem -LiteralPath $dir
}

Обратите внимание на использование + - конкатенации массивов, в данном случае - для обеспечения создания flat массива путей; напротив, 'C:/dir1', 'C:/dir2', (Convert-Path 'C:/dir[3-5]) создаст вложенный массив с путями, разрешенными с использованием подстановочных знаков, которые будут храниться в подмассиве, сохраненном в последнем элементе выходного массива.
Учитывая, что Get-ChildItem -LiteralPath также принимает массивы , это не приведет к ошибке, но не приведет к один за другим dir. обработка.


[1] Существует также Resolve-Path командлет , но он возвращает [System.Management.Automation.PathInfo] экземпляры, которые здесь не нужны, поскольку это строки которые связываются с -LiteralPath.
Кроме того, Convert-Path всегда возвращает фактический путь к файловой системе , тогда как Resolve-Path разрешает пути, основанные на PS-диске , если это применимо - хотя здесь это не имеет значения, если бы вы передавали пути к методам .NET, например.

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