Как найти файлы с длиной пути более 260 символов в Windows?
Я использую xcopy в скрипте Windows XP для рекурсивного копирования каталога. Я продолжаю получать ошибку "недостаточно памяти", которая, как я понимаю, связана с тем, что файл, который я пытаюсь скопировать, имеет слишком длинный путь. Я могу легко уменьшить длину пути, но, к сожалению, я не могу понять, какие файлы нарушают ограничение длины пути. Скопированные файлы выводятся на стандартный вывод (который я перенаправляю в файл журнала), но сообщение об ошибке выводится на терминал, поэтому я не могу даже приблизительно определить, для какого каталога выдается ошибка.
8 ответов:
сделать
dir /s /b > out.txtа затем добавить направляющую в положение 260в powershell
cmd /c dir /s /b |? {$_.length -gt 260}
Я создал инструмент проверки длины пути для этой цели, которая является хорошим, бесплатное приложение GUI, которое вы можете использовать, чтобы увидеть длину пути всех файлов и каталогов в данном каталоге.
Я тоже написал и написал в блоге о простом сценарии PowerShell для получения длины файлов и каталогов. Он выведет длину и путь к файлу и, возможно, запишет его на консоль. Это не ограничивает отображение файлов, которые находятся только над a определенная длина (простая модификация), но отображает их по убыванию длины, поэтому по-прежнему очень легко увидеть, какие пути находятся за вашим порогом. Вот это:
$pathToScan = "C:\Some Folder" # The path to scan and the the lengths for (sub-directories will be scanned as well). $outputFilePath = "C:\temp\PathLengths.txt" # This must be a file in a directory that exists and does not require admin rights to write to. $writeToConsoleAsWell = $true # Writing to the console will be much slower. # Open a new file stream (nice and fast) and write all the paths and their lengths to it. $outputFileDirectory = Split-Path $outputFilePath -Parent if (!(Test-Path $outputFileDirectory)) { New-Item $outputFileDirectory -ItemType Directory } $stream = New-Object System.IO.StreamWriter($outputFilePath, $false) Get-ChildItem -Path $pathToScan -Recurse -Force | Select-Object -Property FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}} | Sort-Object -Property FullNameLength -Descending | ForEach-Object { $filePath = $_.FullName $length = $_.FullNameLength $string = "$length : $filePath" # Write to the Console. if ($writeToConsoleAsWell) { Write-Host $string } #Write to the file. $stream.WriteLine($string) } $stream.Close()
как уточнение простейшего решения, и если вы не можете или не хотите устанавливать Powershell, просто запустите:
dir /s /b | sort /r /+261 > out.txtили (быстрее):
dir /s /b | sort /r /+261 /o out.txtи строки длиннее 260 попадут в верхнюю часть списка. Обратите внимание, что для сортировки столбца необходимо добавить 1 параметр (/+n).
вы можете перенаправить stderr.
больше объяснений здесь, но имея команду, как:
MyCommand >log.txt 2>errors.txtдолжны захватить данные, которые вы ищете.
кроме того, как трюк, Windows обходит это ограничение, если путь имеет префикс
\?\( msdn)еще один трюк, если у вас есть корень или пункт назначения, который начинается с длинного пути, возможно
SUBSTпоможем:SUBST Q: "C:\Documents and Settings\MyLoginName\My Documents\MyStuffToBeCopied" Xcopy Q:\ "d:\Where it needs to go" /s /e SUBST Q: /D
от http://www.powershellmagazine.com/2012/07/24/jaap-brassers-favorite-powershell-tips-and-tricks/:
Get-ChildItem –Force –Recurse –ErrorAction SilentlyContinue –ErrorVariable AccessDeniedпервая часть просто перебирает это и подпапки; используя
-ErrorVariable AccessDeniedозначает, что оскорбительные элементы помещаются в переменную powershellAccessDenied.затем вы можете сканировать переменную так
$AccessDenied | Where-Object { $_.Exception -match "must be less than 260 characters" } | ForEach-Object { $_.TargetObject }если вы не заботитесь об этих файлах (может быть применимо в некоторых случаях), просто удалить
-ErrorVariable AccessDeniedчасть.
Я сделал альтернативу другим хорошим ответам здесь, которые используют PowerShell, но мой также сохраняет список в файл. Поделюсь им здесь, Если кто-то еще захочет что-то подобное.
предупреждение: код перезаписывает " longfilepath.txt " в текущем рабочем каталоге. Я знаю, что это маловероятно, что у вас уже есть один, но на всякий случай!
нарочно хотел его в одну строку:
Out-File longfilepath.txt ; cmd /c "dir /b /s /a" | ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}}подробно инструкции:
- Запустите PowerShell
- перейдите в каталог, который вы хотите проверить на длину пути к файлу (C: works)
- скопируйте и вставьте код [щелкните правой кнопкой мыши, чтобы вставить в PowerShell, или Alt + Space > E > P]
- подождите, пока это не будет сделано, а затем просмотрите файл:
cat longfilepath.txt | sortобъяснение:
Out-File longfilepath.txt ;- создать (или перезаписать) пустой файл под названием 'longfilepath.txt'. С запятой до отдельная команда.
cmd /c "dir /b /s /a" |- выполнить команду dir на PowerShell,/aпоказать все файлы, включая скрытые файлы.|в трубу.
ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}}– для каждой строки (обозначенной как $_), если длина больше 250, добавьте эту строку в файл.
TLPD ("too long path directory") - это программа, которая спасла меня. Очень проста в использовании:
для путей больше 260:
вы можете использовать:Get-ChildItem | Where-Object {$_.FullName.Length -gt 260}пример на 14 символов:
Для просмотра длины путей:Get-ChildItem | Select-Object -Property FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}получить пути больше, чем 14:
Get-ChildItem | Where-Object {$_.FullName.Length -gt 14}скриншоты:
для имен файлов больше 10:
Get-ChildItem | Where-Object {$_.PSChildName.Length -gt 10}скриншоты:


Comments