ฉันจะค้นหาไฟล์ที่มีความยาวพา ธ มากกว่า 260 อักขระใน Windows ได้อย่างไร


87

ฉันใช้ xcopy ในสคริปต์ Windows XP เพื่อคัดลอกไดเรกทอรีแบบวนซ้ำ ฉันได้รับข้อผิดพลาด 'หน่วยความจำไม่เพียงพอ' อยู่เรื่อย ๆ ซึ่งฉันเข้าใจว่าเป็นเพราะไฟล์ที่ฉันพยายามคัดลอกมีเส้นทางที่ยาวเกินไป ฉันสามารถลดความยาวของเส้นทางได้อย่างง่ายดาย แต่น่าเสียดายที่ฉันไม่สามารถระบุได้ว่าไฟล์ใดที่ละเมิดข้อจำกัดความยาวของเส้นทาง ไฟล์ที่คัดลอกจะถูกพิมพ์ไปยังเอาต์พุตมาตรฐาน (ซึ่งฉันกำลังเปลี่ยนเส้นทางไปยังไฟล์บันทึก) แต่ข้อความแสดงข้อผิดพลาดถูกพิมพ์ไปที่เทอร์มินัลดังนั้นฉันจึงไม่สามารถคำนวณได้ว่าไดเร็กทอรีใดมีข้อผิดพลาด .


คำตอบ:


114

ทำ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 Console
รามี

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 บิต Home Premium, Powershell 2.0 - เมื่อฉันสร้างไฟล์ทดสอบที่มีชื่อยาว (240 ตัวอักษร) แล้วเปลี่ยนชื่อไดเรกทอรีที่มันนั่งยังมีชื่อยาวGet-ChildItems -r *หยุดเห็นไฟล์ ... เพียงdir /s /bตามแนวพระราชดำริ สำหรับฉัน.
Jonas Heidelberg

ดูคำตอบของฉันสำหรับวิธีที่จะบรรลุสิ่งนี้ใน powershell ซึ่งช่วยให้คุณสามารถค้นหาชื่อไฟล์ที่ละเมิด (ที่สูงกว่า 260 อักขระ) หรือไม่ก็เพิกเฉย
Jonno

32

ฉันสร้างเครื่องมือ Path Length Checkerเพื่อจุดประสงค์นี้ซึ่งเป็นแอป GUI ที่ดีและฟรีที่คุณสามารถใช้เพื่อดูความยาวพา ธ ของไฟล์และไดเร็กทอรีทั้งหมดในไดเร็กทอรีที่กำหนด

ฉันยังเขียนและเขียนบล็อกเกี่ยวกับสคริปต์ 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 HDD โดยเครื่องมือนี้มาทำความรู้จักกับความยาวสูงสุดในการสร้างโครงสร้างโฟลเดอร์บน HDD ขอบคุณ.
NJMR

เครื่องมือที่ยอดเยี่ยม! ฉันใช้มันเพื่อสร้างสคริปต์ที่สามารถค้นหาไฟล์ / โฟลเดอร์ทั้งหมดที่มีพา ธ ยาวกว่า 247 อักขระซึ่งเป็นขีด จำกัด สำหรับ Synology Drive Client ใน Windows รหัสหลักคือPathLengthChecker.exe RootDirectory="C:\[MyFolder]" MinLength=248ในขณะที่echo SELECT sync_folder FROM session_table;| sqlite3.exe %LocalAppData%\SynologyDrive\data\db\sys.sqliteจำเป็นในการรับโฟลเดอร์แชร์ทางโปรแกรม (หากคุณสนใจรหัสแบบเต็มโปรดสอบถาม)
Kar.ma

เครื่องมือที่ยอดเยี่ยมขอบคุณ สำหรับงาน Rsync ระหว่าง 2 Synology NAS ของฉันฉันควรรู้ FILENAMES ทั้งหมดที่ยาวกว่า 143 ตัวอักษร นี่ไม่ใช่ความยาวเส้นทางทั้งหมดเป็นเพียงความยาวสูงสุดต่อชื่อไฟล์ ฉันจะค้นหาชื่อไฟล์ดังกล่าวได้อย่างไร
PeterCo

1
เฮ้ @PeterCo คุณยังสามารถใช้สคริปต์ PowerShell ด้านบนได้ แต่แทนที่จะใช้$_.FullNameเพียงแค่แทนที่ด้วย$_.Nameทุกที่ ที่จะให้ชื่อไฟล์แทนพา ธ แบบเต็ม
Deadlydog

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) โหวต
preOtep

อธิบายได้ไหมว่าทำไมต้องเพิ่ม 1 ในรายละเอียด
Xonatron

มีวิธีจัดเรียงไฟล์เอาต์พุตตามความยาวบรรทัดหรือไม่?
Xonatron

@Xonatron "และเส้นยาวกว่า 260"
cliffclof

โหวตขึ้น ฉันคิดว่าสิ่งนี้ควรพูดถึง SUBST เพื่อย่นเส้นทางลงในไดรฟ์ ftw
หน้าผา

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: works)
  3. คัดลอกและวางโค้ด [คลิกขวาเพื่อวางใน PowerShell หรือ Alt + Space> 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> file 2> & 1
WestHamster

ซึ่งจะใช้งานได้ แต่คำสั่งของฉันควรแยกข้อผิดพลาดออกเป็นไฟล์แยกต่างหาก
SeanC

\\? \ ก็ดูดีเหมือนกัน ฉันไม่สามารถใช้สิ่งต่อไปนี้ได้: xcopy / s \\? \ Q: \ nuthatch \\? \ Q: \ finch
WestHamster

อืม ... ดูเหมือน\\?\ จะใช้ไม่ได้กับบรรทัดคำสั่ง เพิ่มแนวคิดอื่นโดยใช้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 PowerShellAccessDenied

จากนั้นคุณสามารถสแกนผ่านตัวแปรเช่นนั้น

$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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.