Pregunta

Estoy usando xcopy en un script de Windows XP para copiar recursivamente un directorio.Sigo recibiendo el error "Memoria insuficiente", y entiendo que se debe a que el archivo que estoy intentando copiar tiene una ruta demasiado larga.Puedo reducir fácilmente la longitud de la ruta, pero desafortunadamente no puedo determinar qué archivos violan la restricción de longitud de la ruta.Los archivos que se copian se imprimen en la salida estándar (que estoy redirigiendo a un archivo de registro), pero el mensaje de error se imprime en la terminal, por lo que ni siquiera puedo calcular aproximadamente para qué directorio se proporciona el error. .

¿Fue útil?

Solución

hacer un dir /s /b > out.txt y luego agregue una guía en la posición 260

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

Otros consejos

He creado la herramienta de corrector de longitud de la ruta Para este propósito, que es una aplicación GUI gratuita y gratuita quePuede usar para ver las longitudes de la ruta de todos los archivos y directorios en un directorio determinado.

También tengo una escrito y blogueado sobre un script simple de PowerShell para obtener longitudes de archivo y directorio.Guardará la longitud y la ruta a un archivo, y opcionalmente lo escribirá también a la consola.No se limita a mostrar archivos que solo tienen una longitud determinada (una modificación fácil para hacer), pero las muestra descendentes de la longitud, por lo que aún es muy fácil ver qué rutas están sobre su umbral.Aquí está:

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

Como refinamiento de la solución más sencilla, y si no puede o no quiere instalar PowerShell, simplemente ejecute:

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

o (más rápido):

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

y las líneas de más de 260 llegarán a la parte superior del listado.Tenga en cuenta que debe agregar 1 para ordenar el parámetro de columna (/ + n).

Creé una alternativa a las otras buenas respuestas aquí que usa PowerShell, pero la mía también guarda la lista en un archivo.Lo compartiré aquí en caso de que alguien más necesite algo así.

Advertencia: El código sobrescribe "longfilepath.txt" en el directorio de trabajo actual.Sé que es poco probable que ya tengas uno, ¡pero por si acaso!

Lo quería a propósito en una sola línea:

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

Instrucciones detalladas:

  1. Ejecute PowerShell
  2. Vaya al directorio donde desea verificar la longitud de la ruta de archivo (C:obras)
  3. Copie y pegue el código [haga clic derecho para pegar en PowerShell, o Alt + Espacio > E > P]
  4. Espere hasta que termine y luego vea el archivo: cat longfilepath.txt | sort

Explicación:

Out-File longfilepath.txt ; – Cree (o sobrescriba) un archivo en blanco titulado 'longfilepath.txt'.Punto y coma para separar comandos.

cmd /c "dir /b /s /a" | – Ejecute el comando dir en PowerShell, /a para mostrar todos los archivos, incluidos los archivos ocultos. | a la tubería.

ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}} – Para cada línea (indicada como $_), si la longitud es mayor que 250, agregue esa línea al archivo.

Puede redirigir STDERR.

Más explicación aquí , pero teniendo un comando como:

MyCommand >log.txt 2>errors.txt

debe tomar los datos que está buscando.

también, como un truco, Windows pasa por alto esa limitación si la ruta está prefijada con \\?\ ( msdn )

Otro truco Si tiene una raíz o un destino que comienza con un camino largo, tal vez GeneracDicetAnDode lo ayudará:

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

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

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

la primera parte simplemente recorre en iteración esta y las subcarpetas;usando -ErrorVariable AccessDenied significa empujar los elementos ofensivos en la variable de PowerShell AccessDenied.

Luego puede escanear la variable así

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

Si no le interesan estos archivos (puede ser aplicable en algunos casos), simplemente suelte el -ErrorVariable AccessDenied parte.

TLPD ("Directorio de ruta demasiado largo") es el programa que me ahorró. Muy fácil de usar:

https://sourceforge.net/projects/tlpd/

para caminos superiores a 260:

Puedes usar:

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

Ejemplo en 14 caracteres:

Para ver las trayectorias longitudes:

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

obtener rutas superiores a 14:

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

captura de pantalla:

ingrese la descripción de la imagen aquí

para los nombres de archivo superiores a 10:

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

captura de pantalla:

ingrese la descripción de la imagen aquí

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top