Làm cách nào để tìm tệp có độ dài đường dẫn lớn hơn 260 ký tự trong Windows?


87

Tôi đang sử dụng một xcopy trong tập lệnh windows XP để sao chép đệ quy một thư mục. Tôi tiếp tục gặp lỗi 'Bộ nhớ không đủ', tôi hiểu là do tệp tôi đang cố sao chép có đường dẫn quá dài. Tôi có thể dễ dàng giảm độ dài đường dẫn, nhưng rất tiếc là tôi không thể tìm ra tệp nào đang vi phạm giới hạn độ dài đường dẫn. Các tệp được sao chép được in ra đầu ra tiêu chuẩn (mà tôi đang chuyển hướng đến tệp nhật ký), nhưng thông báo lỗi được in đến thiết bị đầu cuối, vì vậy tôi thậm chí không thể tìm ra lỗi đang được đưa ra cho thư mục nào .


Câu trả lời:


114

làm một dir /s /b > out.txtvà sau đó thêm một hướng dẫn ở vị trí 260

Trong quyền hạn cmd /c dir /s /b |? {$_.length -gt 260}


1
dir / s / b> out.txt thực hiện công việc tuyệt vời. Cảm ơn. "'Get-ChildItem' không được nhận dạng là lệnh bên trong hoặc bên ngoài, chương trình có thể hoạt động hoặc tệp hàng loạt." Tôi đoán tôi không có powershell.
WestHamster

1
@WestHamster, bạn sẽ phải chạy lệnh đó trong PowerShell Console.
Rami A.

6
Nó xuất hiện một lỗi như: 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.Cùng với nó, chỉ có một đường dẫn rút gọn được in. ví dụ: D:\Dropbox\ProY...sh._setbinddata. Đó chính xác là những con đường tôi muốn tìm, nhưng tôi không thể nhìn thấy toàn bộ con đường! Bất kỳ cách nào xung quanh điều này?
MiniGod

Tôi có phải là người duy nhất không thể làm việc này? Sử dụng Win7 64 bit Home Premium, Powershell 2.0 - khi tôi tạo một tệp thử nghiệm có tên dài (240 ký tự) và sau đó đổi tên thư mục chứa nó để có tên dài, Get-ChildItems -r *dừng nhìn thấy tệp ... chỉ dir /s /bhoạt động cho tôi.
Jonas Heidelberg

Xem câu trả lời của tôi để biết cách đạt được điều này trong powershell, cho phép bạn tìm tên tệp vi phạm (những tên trên 260 ký tự) hoặc cách khác, bỏ qua chúng.
Jonno

31

Tôi đã tạo công cụ Kiểm tra độ dài đường dẫn cho mục đích này, đây là một ứng dụng GUI miễn phí, đẹp mắt mà bạn có thể sử dụng để xem độ dài đường dẫn của tất cả các tệp và thư mục trong một thư mục nhất định.

Tôi cũng đã viết và viết blog về một tập lệnh PowerShell đơn giản để lấy độ dài tệp và thư mục. Nó sẽ xuất ra độ dài và đường dẫn đến một tệp, và tùy chọn ghi nó vào bảng điều khiển. Nó không giới hạn việc hiển thị các tệp chỉ có độ dài nhất định (một sửa đổi dễ thực hiện), nhưng hiển thị chúng giảm dần theo độ dài, vì vậy, vẫn rất dễ dàng để xem đường dẫn nào vượt quá ngưỡng của bạn. Nó đây:

$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
Tập lệnh thú vị, nhưng tôi vẫn gặp lỗi này: 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

Công cụ tuyệt vời !! Tôi đã có một ngày lớn, muốn tạo một bản sao lưu trên ổ cứng WD MyCloud. Bằng công cụ này đã biết độ dài tối đa để tạo cấu trúc thư mục trên ổ cứng. Cảm ơn.
NJMR

27

Như một sự cải tiến của giải pháp đơn giản nhất và nếu bạn không thể hoặc không muốn cài đặt Powershell, chỉ cần chạy:

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

hoặc (nhanh hơn):

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

Và các dòng dài hơn 260 sẽ lên đầu danh sách. Lưu ý rằng bạn phải thêm 1 vào tham số cột SORT (/ + n).


Cảm ơn vì sự sàng lọc. Đó là trường hợp của tôi mà tôi không thể cài đặt Powershell (hộp Windows 2003). Bầu lên
preOtep

Bạn có thể giải thích lý do tại sao bạn phải thêm 1 chi tiết hơn?
Xonatron

Có cách nào để sắp xếp tệp đầu ra theo độ dài dòng không?
Xonatron

@Xonatron, "Và các dòng dài hơn 260"
Clipsclof

Lên bình chọn. Tôi nghĩ rằng điều này cũng nên đề cập đến SUBST để rút ngắn một đường dẫn vào một ổ đĩa ftw.
vách đá

6

Tôi đã thực hiện một giải pháp thay thế cho các câu trả lời hay khác ở đây là sử dụng PowerShell, nhưng tôi cũng lưu danh sách vào một tệp. Sẽ chia sẻ nó ở đây trong trường hợp bất cứ ai khác cần muốn một cái gì đó như vậy.

Cảnh báo: Mã ghi đè "longfilepath.txt" trong thư mục làm việc hiện tại. Tôi biết chưa chắc bạn đã có, nhưng đề phòng!

Có chủ đích muốn nó trong một dòng:

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

Hướng dẫn chi tiết:

  1. Chạy PowerShell
  2. Di chuyển đến thư mục bạn muốn kiểm tra độ dài đường dẫn tệp (C: \ works)
  3. Sao chép và dán mã [Nhấp chuột phải để dán vào PowerShell hoặc Alt + Space> E> P]
  4. Chờ cho đến khi hoàn tất và sau đó xem tệp: cat longfilepath.txt | sort

Giải trình:

Out-File longfilepath.txt ;- Tạo (hoặc ghi đè) một tệp trống có tiêu đề 'longfilepath.txt'. Dấu chấm phẩy để phân cách các lệnh.

cmd /c "dir /b /s /a" |- Chạy lệnh dir trên PowerShell, /ađể hiển thị tất cả các tệp kể cả tệp ẩn. |vào đường ống.

ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}} - Với mỗi dòng (ký hiệu là $ _), nếu độ dài lớn hơn 250 thì nối dòng đó vào tệp.


2

bạn có thể chuyển hướng stderr.

giải thích thêm ở đây , nhưng có một lệnh như:

MyCommand >log.txt 2>errors.txt

nên lấy dữ liệu bạn đang tìm kiếm.

Ngoài ra, như một thủ thuật, Windows sẽ bỏ qua giới hạn đó nếu đường dẫn có tiền tố là \\?\( msdn )

Một mẹo khác nếu bạn có gốc hoặc đích bắt đầu với một đường dẫn dài, có lẽ SUBSTsẽ hữu ích:

SUBST Q: "C:\Documents and Settings\MyLoginName\My Documents\MyStuffToBeCopied"
Xcopy Q:\ "d:\Where it needs to go" /s /e
SUBST Q: /D

Chuyển hướng đầu ra std và các lỗi sẽ cho tôi một dấu hiệu đủ tốt về vị trí của tệp lớn. lệnh> tập 2> & 1
WestHamster

mà sẽ làm việc, nhưng lệnh của tôi nên tách các lỗi thành một file riêng biệt
SeanC

\\? \ cũng có vẻ tốt. Mặc dù vậy, tôi không thể làm cho những thứ sau hoạt động: xcopy / s \\? \ Q: \ nuthatch \\? \ Q: \ finch
WestHamster

hmm ... có vẻ như \\?\ không hoạt động đối với dòng lệnh. Thêm một ý tưởng sử dụngSUBST
SeanC

Thật không may subst sẽ không quá hữu ích vì lệnh là loại: xcopy / sq: \ loại chim chỉ ăn trái đào nhỏ và côn trùng q: \ finch <br/> và con đường dài được nhúng ở đâu đó chưa được biết dưới loại chim chỉ ăn trái đào nhỏ và
WestHamster

2

Từ http://www.powershellmagazine.com/2012/07/24/jaap-brassers-favorite-powershell-tips-and-tricks/ :

Get-ChildItem –Force –Recurse –ErrorAction SilentlyContinue –ErrorVariable AccessDenied

phần đầu tiên chỉ lặp qua thư mục này và các thư mục con; sử dụng -ErrorVariable AccessDeniedcó nghĩa là đẩy các mục vi phạm vào biến powershell AccessDenied.

Sau đó, bạn có thể quét qua biến như vậy

$AccessDenied |
Where-Object { $_.Exception -match "must be less than 260 characters" } |
ForEach-Object { $_.TargetObject }

Nếu bạn không quan tâm đến những tệp này (có thể áp dụng trong một số trường hợp), chỉ cần bỏ -ErrorVariable AccessDeniedphần đó.


Vấn đề là, $_.TargetObjectkhông chứa đường dẫn đầy đủ đến các tệp vi phạm MAX_PATH, chỉ có tên Thư mụctên thư mục mẹ của các tệp vi phạm. Tôi đang tìm kiếm giải pháp không phải Robocopy hoặc Subst hoặc Xcopy và sẽ đăng khi tôi tìm thấy giải pháp hiệu quả.
user66001 15/12/15


-2

Đối với các đường dẫn lớn hơn 260:
bạn có thể sử dụng:

Get-ChildItem | Where-Object {$_.FullName.Length -gt 260}

Ví dụ về 14 ký tự:
Để xem độ dài đường dẫn:

Get-ChildItem | Select-Object -Property FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}

Nhận đường dẫn lớn hơn 14:

Get-ChildItem | Where-Object {$_.FullName.Length -gt 14}  

Ảnh chụp màn hình:
nhập mô tả hình ảnh ở đây

Đối với tên tệp lớn hơn 10:

Get-ChildItem | Where-Object {$_.PSChildName.Length -gt 10}

Ảnh chụp màn hình:
nhập mô tả hình ảnh ở đây


4
Bạn rõ ràng không có ý tưởng về vấn đề này. Không có gì trong số những gì bạn đề xuất hoạt động. Hãy đọc
n0rd
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.