powershell: найдите подкаталоги с самыми длинными путями - PullRequest
2 голосов
/ 21 января 2020

Я хотел бы найти самые длинные пути среди подкаталогов в данном каталоге, потому что я столкнулся с этой ошибкой:

The specified path, file name, or both are too long.
The fully qualified file name must be less than 260 characters, 
and the directory name must be less than 248 characters.

Это то, что я пробовал:

$dir = "\\share\server\toto" 
Get-ChildItem -Path $dir -Recurse -Directory | 
Select-Object Name,FullName,
@{Name='FileCount';Expression = {(Get-ChildItem -Path $_.FullName -File -Recurse| Measure-Object).Count}} `
| Format-List *

но это дает мне все каталогов.

Вместо этого я хочу найти топ-5 каталогов с самыми длинными путями.

Ответы [ 2 ]

2 голосов
/ 21 января 2020

Возвращает 5 каталогов с самыми длинными путями:

Get-ChildItem -Path $dir -Recurse -Directory | % { $_.FullName } | Sort-Object { $_.Length } -Descending | Select -first 5
1 голос
/ 21 января 2020

В сообщении об ошибке указывается, что поддержка длинных путей [1] не включена в вашей системе - на Windows 10, теперь вы можете включить ее для всей системы для . NET Framework v4.6.2 + приложения - см. этот ответ .

С поддержкой длинного пути отключено , Get-ChildItemGet-Item) не найдет файлы и каталоги со слишком длинными именами файлов в Windows PowerShell .

В отличие от этого PowerShell [Core] v6 + поддержка длинных путей включена по умолчанию, и никакой дополнительной работы не требуется - то есть ваша проблема даже не возникла бы там.

В Windows PowerShell, чтобы найти слишком длинные пути с длинным путем поддержка отключена, вам нужно добавить префикс длинного пути к full , буквальному, нормализованному целевому пути :

  • Для локальных путей этот префикс \\?\; например, '\\?\C:\temp'

  • Для UN C путей , префикс \\?\UNC\, с первый \ удален из пути ООН C ; например, '\\?\UNC\share\server\toto'

Следующая команда находит все пути подкаталогов, которые являются слишком длинными (независимо от их количества) , отсортированные по длине пути в порядке убывания :

# $dir = ...  # set the target dir.

# Construct the long-path-opt-in form of the path (covers both local and UNC paths).
$dirLongPaths = ('\\?\' + (Convert-Path $dir)) -replace '^(\\\\[?]\\)\\\\', '$1UNC\'

Get-ChildItem -LiteralPath $dirLongPaths -Recurse -Directory | 
  Where-Object { $_.FullName.Length -ge 248 } |
    Sort-Object -Descending -Property { $_.FullName.Length } | 
      Select-Object -Property Name, FullName, @{
        Name='FileCount';
        Expression = {(Get-ChildItem -LiteralPath $_.FullName -File -Recurse).Count}
      } | Format-List

Обратите внимание, что я упростила блок сценариев Expression, просто получив прямой доступ к .Count непосредственно к результату вызова Get-ChildItem.

Примечание вызов Sort-Object, который сортируется в порядке убывания (-Descending) по вычисляемому свойству { $_.FullName.Length }, т. е. по длине полного пути каждого входного объекта каталога-информации (.FullName)

Также обратите внимание что префикс \\?\ равен , а не также применяется к вложенному Get-ChildItem вызову, поскольку первый вызов выводит объекты каталогов-информации, свойство .FullName которых уже включает префикс.


[1] Исторически пути файловой системы были ограничены 259 символами. в целом и до 247 символов. для части каталога пути к файлу. По умолчанию эти ограничения все еще применяются ради обратной совместимости, даже если базовые API больше не связаны этими ограничениями. Системы / приложения могут снять эти ограничения с помощью механизма opt-in .

...