Jak znaleźć pliki o długości ścieżki większej niż 260 znaków w systemie Windows?

87

Używam xcopy w skrypcie systemu Windows XP, aby rekurencyjnie skopiować katalog. Ciągle pojawia się błąd „Za mało pamięci”, co rozumiem, ponieważ plik, który próbuję skopiować, ma zbyt długą ścieżkę. Mogę łatwo zmniejszyć długość ścieżki, ale niestety nie mogę ustalić, które pliki naruszają ograniczenie długości ścieżki. Pliki, które są kopiowane, są drukowane na standardowe wyjście (które przekierowuję do pliku dziennika), ale komunikat o błędzie jest drukowany na terminalu, więc nie mogę nawet zorientować się, w którym katalogu błąd jest podawany .

WestHamster
źródło

Odpowiedzi:

114

wykonaj a, dir /s /b > out.txta następnie dodaj prowadnicę w pozycji 260

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

ponowne odtworzenie
źródło
1
dir / s / b> out.txt świetnie sobie radzi. Dzięki. „'Get-ChildItem' nie jest rozpoznawane jako polecenie wewnętrzne lub zewnętrzne, program operacyjny lub plik wsadowy.” Chyba nie mam PowerShell.
WestHamster
1
@WestHamster, musisz uruchomić to polecenie w konsoli PowerShell.
Rami A.
6
Wyświetla błąd typu: 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.Wraz z nim drukowana jest tylko skrócona ścieżka. np D:\Dropbox\ProY...sh._setbinddata. : . To są dokładnie ścieżki, które chcę znaleźć, ale nie widzę całej ścieżki! Jakoś to obejść?
MiniGod
Czy jestem jedynym, który nie może sprawić, by to zadziałało? Używając Win7 64 bit Home Premium, Powershell 2.0 - kiedy tworzę plik testowy o długiej nazwie (240 znaków), a następnie zmieniam nazwę katalogu, w którym się znajduje, aby również miał długą nazwę, Get-ChildItems -r *przestaje widzieć plik ... dir /s /bdziała tylko dla mnie.
Jonas Heidelberg
Zobacz moją odpowiedź, aby dowiedzieć się, jak to osiągnąć w programie PowerShell, umożliwiając znalezienie niewłaściwych nazw plików (powyżej 260 znaków) lub zignorowanie ich.
Jonno
32

W tym celu stworzyłem narzędzie Path Length Checker , które jest przyjemną, bezpłatną aplikacją z graficznym interfejsem użytkownika, za pomocą której możesz zobaczyć długości ścieżek wszystkich plików i katalogów w danym katalogu.

Napisałem również i opublikowałem na blogu o prostym skrypcie PowerShell do pobierania długości plików i katalogów. Wyświetli długość i ścieżkę do pliku i opcjonalnie zapisze go również w konsoli. Nie ogranicza się do wyświetlania plików, które mają tylko określoną długość (łatwa modyfikacja), ale wyświetla je malejąco według długości, więc nadal bardzo łatwo jest zobaczyć, które ścieżki przekraczają twój próg. Oto ona:

$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()
śmiertelny pies
źródło
2
Ciekawy skrypt, ale nadal otrzymuję ten błąd: 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
Doskonałe narzędzie !! Miałem ogromną randkę, chciałem stworzyć kopię zapasową na dysku WD MyCloud. Dzięki temu narzędziu poznano maksymalną długość tworzenia struktury folderów na dysku twardym. Dzięki.
NJMR
Świetne narzędzie! Użyłem go do stworzenia skryptu, który mógł znaleźć wszystkie pliki / foldery mające ścieżkę dłuższą niż 247 znaków, co jest limitem dla klienta Synology Drive w systemie Windows. Główny kod to PathLengthChecker.exe RootDirectory="C:\[MyFolder]" MinLength=248, podczas gdy echo SELECT sync_folder FROM session_table;| sqlite3.exe %LocalAppData%\SynologyDrive\data\db\sys.sqlitebył potrzebny do programowego pobrania folderów współdzielonych. (Jeśli jesteś zainteresowany pełnym kodem, możesz zapytać)
Kar.ma
Świetne narzędzie, dziękuję. W przypadku mojego zadania Rsync między 2 serwerami Synology NAS powinienem znać wszystkie NAZWY PLIKÓW dłuższe niż 143 znaki. To nie jest cała długość ścieżki, a jedynie maksymalna długość na nazwę pliku. Jak mogłem znaleźć takie nazwy plików?
PeterCo
1
Hej @PeterCo, nadal możesz używać powyższego skryptu PowerShell, ale zamiast używać go $_.FullNamepo prostu zastąp go $_.Namewszędzie; dzięki temu zamiast pełnej ścieżki otrzymasz nazwę pliku.
śmiertelny pies
27

Jako udoskonalenie najprostszego rozwiązania, a jeśli nie możesz lub nie chcesz zainstalować Powershell, po prostu uruchom:

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

lub (szybciej):

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

A linie dłuższe niż 260 zostaną umieszczone na początku listy. Zauważ, że musisz dodać 1 do parametru kolumny SORT (/ + n).

Chungalin
źródło
Dzięki za uszlachetnienie. To był mój przypadek, że nie mogłem zainstalować Powershell (box z Windows 2003). Wziął UP
preOtep
Czy możesz wyjaśnić, dlaczego musisz dodać 1 bardziej szczegółowo?
Xonatron
Czy istnieje sposób sortowania pliku wyjściowego według długości linii?
Xonatron
@Xonatron, „I linie dłuższe niż 260”
cliffclof,
Głosowałem w górę. Myślę, że powinno to również wspomnieć o SUBST, aby skrócić ścieżkę do napędu ftw.
cliffclof
6

Zrobiłem alternatywę dla innych dobrych odpowiedzi tutaj, które używają PowerShell, ale moja również zapisuje listę do pliku. Podzielę się tym tutaj na wypadek, gdyby ktoś inny chciał czegoś takiego.

Ostrzeżenie: kod nadpisuje plik „longfilepath.txt” w bieżącym katalogu roboczym. Wiem, że jest mało prawdopodobne, że już go masz, ale na wszelki wypadek!

Celowo chciałem to w jednej linii:

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

Szczegółowe instrukcje:

  1. Uruchom PowerShell
  2. Przejdź do katalogu, w którym chcesz sprawdzić długości ścieżek plików (C: działa)
  3. Skopiuj i wklej kod [kliknij prawym przyciskiem myszy, aby wkleić w PowerShell lub Alt + Spacja> E> P]
  4. Poczekaj, aż to się skończy, a następnie wyświetl plik: cat longfilepath.txt | sort

Wyjaśnienie:

Out-File longfilepath.txt ;- Utwórz (lub nadpisz) pusty plik o nazwie „longfilepath.txt”. Średnik do oddzielania poleceń.

cmd /c "dir /b /s /a" |- Uruchom polecenie dir w PowerShell, /aaby wyświetlić wszystkie pliki, w tym pliki ukryte. |do rury.

ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}} - Dla każdej linii (oznaczonej jako $ _), jeśli długość jest większa niż 250, dołącz tę linię do pliku.

Rani Kheir
źródło
2

możesz przekierować stderr.

więcej wyjaśnień tutaj , ale mając polecenie takie jak:

MyCommand >log.txt 2>errors.txt

powinien pobrać dane, których szukasz.

Ponadto, jako sztuczka, system Windows omija to ograniczenie, jeśli ścieżka jest poprzedzona prefiksem \\?\( msdn )

Inna sztuczka, jeśli masz korzeń lub miejsce docelowe, które zaczyna się od długiej ścieżki, być SUBSTmoże pomoże:

SUBST Q: "C:\Documents and Settings\MyLoginName\My Documents\MyStuffToBeCopied"
Xcopy Q:\ "d:\Where it needs to go" /s /e
SUBST Q: /D
SeanC
źródło
Przekierowanie wyjścia standardowego i błędów powinno dać mi wystarczająco dobre wskazanie, gdzie jest dziękuję duży plik. polecenie> plik 2> & 1
WestHamster
to zadziała, ale moje polecenie powinno rozdzielić błędy w osobnym pliku
SeanC
\\? \ też wygląda dobrze. Nie mogę jednak uruchomić następujących elementów: xcopy / s \\? \ Q: \ nuthatch \\? \ Q: \ finch
WestHamster
hmm ... wygląda na \\?\ to, że nie działa dla wiersza poleceń. Dodano inny pomysł przy użyciuSUBST
SeanC
Niestety subst nie będzie zbyt przydatna, ponieważ polecenie jest typu: xcopy / sq: \ nuthatch q: \ finch <br/>, a długa ścieżka jest osadzona w nieznanym miejscu pod nuthatch
WestHamster
2

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

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

pierwsza część po prostu przechodzi przez to i podfoldery; za pomocą -ErrorVariable AccessDeniedśrodków wypycha niewłaściwe elementy do zmiennej PowerShell AccessDenied.

Następnie możesz przejrzeć zmienną w ten sposób

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

Jeśli nie dbasz o te pliki (może to mieć zastosowanie w niektórych przypadkach), po prostu usuń -ErrorVariable AccessDeniedczęść.

Jonno
źródło
Problem jest, $_.TargetObjectnie zawiera pełną ścieżkę do plików , które naruszają MAX_PATH, tylko nazwy katalogów , a także nazwę katalogu nadrzędnego plików przestępczych. Pracuję nad znalezieniem rozwiązania innego niż Robocopy lub Subst lub Xcopy i napiszę, gdy znajdę działające rozwiązanie.
user66001
-2

W przypadku ścieżek większych niż 260:
możesz użyć:

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

Przykład na 14 znakach:
Aby wyświetlić długości ścieżek:

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

Uzyskaj ścieżki większe niż 14:

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

Zrzut ekranu:
wprowadź opis obrazu tutaj

W przypadku nazw plików większych niż 10:

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

Zrzut ekranu:
wprowadź opis obrazu tutaj

E235
źródło
4
Oczywiście nie masz pojęcia o tym problemie. Żadne z sugestii nie działa. Proszę przeczytać
n0rd