Як знайти файли з довжиною шляху більше 260 символів у Windows?


87

Я використовую xcopy у скрипті Windows XP для рекурсивного копіювання каталогу. Я постійно отримую помилку "Недостатня пам'ять", яку я розумію, оскільки файл, який я намагаюся скопіювати, має занадто довгий шлях. Я легко можу зменшити довжину шляху, але, на жаль, я не можу зрозуміти, які файли порушують обмеження довжини шляху. Копіювані файли друкуються на стандартний вивід (який я перенаправляю у файл журналу), але повідомлення про помилку друкується на терміналі, тому я навіть не можу приблизно визначити, для якого каталогу вказана помилка .


Відповіді:


114

виконайте a, dir /s /b > out.txtа потім додайте напрямну в положенні 260

У PowerShell cmd /c dir /s /b |? {$_.length -gt 260}


1
dir / s / b> out.txt чудово виконує цю роботу. Дякую. "'Get-ChildItem' не розпізнається як внутрішня чи зовнішня команда, операційна програма або пакетний файл." Я думаю, у мене немає PowerShell.
WestHamster

1
@WestHamster, вам доведеться запустити цю команду в консолі PowerShell.
Рамі А.

6
Він видає таку помилку, як: Get-ChildItem : 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.Разом із нею друкується лише скорочений шлях. наприклад: D:\Dropbox\ProY...sh._setbinddata. Це саме ті шляхи, які я хочу знайти, але я не бачу цілого шляху! Будь-який спосіб обійти це?
MiniGod

Я єдиний, хто не може змусити це працювати? Використовуючи Win7 64 bit Home Premium, Powershell 2.0 - коли я створюю тестовий файл із довгим іменем (240 символів), а потім перейменовую каталог, в якому він знаходиться, щоб також мати довге ім’я, Get-ChildItems -r *перестає бачити файл ... dir /s /bпрацює лише для мене.
Йонас Гейдельберг

Перегляньте мою відповідь щодо способу досягнення цього в PowerShell, що дозволяє або знайти неправдиві імена файлів (ті, що перевищують 260 символів), або ж проігнорувати їх.
Джонно,

31

Для цього я створив інструмент перевірки довжини шляху , який є приємним безкоштовним додатком графічного інтерфейсу, за допомогою якого можна побачити довжину шляху всіх файлів та каталогів у певному каталозі.

Я також писав і писав у блогах про простий сценарій PowerShell для отримання довжини файлів і каталогів. Він видасть довжину та шлях до файлу, а також, за бажанням, також напише їх у консоль. Це не обмежує показ файлів, які мають лише певну довжину (легка модифікація), але відображає їх за спаданням за довжиною, тому все одно надзвичайно легко побачити, які шляхи перевищують ваш поріг. Ось:

$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()

2
Цікавий сценарій, але я все ще отримую цю помилку: Get-ChildItem : 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.
zkurtz

Відмінний інструмент !! У мене була величезна дата, я хотів створити резервну копію на жорсткому диску WD MyCloud. За допомогою цього інструменту ми дізналися максимальну довжину для створення структури папок на жорсткому диску. Дякую.
NJMR

27

Як вдосконалення найпростішого рішення, і якщо ви не можете або не хочете встановити Powershell, просто запустіть:

dir /s /b | sort /r /+261 > out.txt

або (швидше):

dir /s /b | sort /r /+261 /o out.txt

А рядки довжиною більше 260 потраплять у верхню частину списку. Зверніть увагу, що потрібно додати 1 до параметра стовпця SORT (/ + n).


Дякую за вдосконалення. Це був мій випадок, що я не зміг встановити Powershell (Windows 2003). ПРОГОЛОСУВАВ UP
preOtep

Чи можете ви пояснити, чому вам потрібно додати 1 детальніше?
Xonatron

Чи є спосіб сортувати вихідний файл за довжиною рядка?
Ксонатрон

@Xonatron, "І рядки довші за 260"
cliffclof

Вгору проголосували. Я думаю, що тут також слід згадати SUBST, щоб скоротити шлях до приводу ftw.
cliffclof

6

Я зробив альтернативу іншим хорошим відповідям тут, який використовує PowerShell, але мій також зберігає список у файл. Поділюсь тут, на випадок, якщо комусь ще знадобиться щось подібне.

Попередження: код перезаписує "longfilepath.txt" у поточному робочому каталозі. Я знаю, що навряд чи у вас він би вже був, але про всяк випадок!

Навмисно хотів це в один рядок:

Out-File longfilepath.txt ; cmd /c "dir /b /s /a" | ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}}

Детальні інструкції:

  1. Запустіть PowerShell
  2. Перейдіть до каталогу, який потрібно перевірити на довжину шляху до файлу (C: працює)
  3. Скопіюйте та вставте код [Клацніть правою кнопкою миші, щоб вставити в PowerShell, або Alt + Пробіл> E> P]
  4. Зачекайте, поки це буде зроблено, а потім перегляньте файл: 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, додайте цей рядок до файлу.


2

ви можете перенаправити 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

Перенаправлення виводу std та помилок повинно дати мені достатньо хорошу вказівку на те, де знаходиться великий файл. command> файл 2> & 1
WestHamster

це буде працювати, але моя команда повинна відокремити помилки в окремий файл
SeanC

\\? \ теж добре виглядає. Однак я не можу змусити працювати наступне: xcopy / s \\? \ Q: \ nuthatch \\? \ Q: \
finch

хм ... здається \\?\ , не працює для командного рядка. Додав ще одну ідею, використовуючиSUBST
SeanC

На жаль, subst не буде надто корисним, оскільки команда має тип: xcopy / sq: \ nuthatch q: \ finch <br/>, а довгий шлях вкладений десь невідомо під
nuthatch

2

З 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частину.


Проблема полягає в тому, $_.TargetObjectщо не містить повного шляху до файлів, які порушують MAX_PATH, лише імена каталогів та ім’я батьківського каталогу файлів-порушників. Я працюю над пошуком рішення, яке не стосується Robocopy, Subst або Xcopy, і розміщу повідомлення, коли знайду робоче рішення.
user66001


-2

Для шляхів більше 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}

Знімок екрана:
введіть тут опис зображення


4
Ви явно не уявляєте про це питання. Жодне з того, що ви запропонували, не працює. Будь ласка, прочитайте
n0rd
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.