Как найти файлы с длиной пути более 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 попадут в начало списка. Обратите внимание, что для сортировки параметра столбца (/+n) необходимо добавить 1.
вы можете перенаправить 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
означает, что вытолкните оскорбительные элементы в переменную powershell AccessDenied
.
затем вы можете сканировать переменную так
$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}
скриншоты: