Recuperar contenido de carpetas y subcarpetas en CSV con rutas relativas

Recuperar contenido de carpetas y subcarpetas en CSV con rutas relativas

Encontré esto para obtener el contenido de una carpeta y su subcarpeta (solo archivos) en un archivo CSV:

dir -recurse | Where-Object { !$_.PSIsContainer } | Select FullName |
convertto-csv | out-file "test.csv"

Sin embargo, en lugar de la ruta completa, me gustaría obtener la ruta relativa (relativa a la raíz desde donde ejecuto el comando).

¿Alguien puede ayudar?

¡Gracias!

Respuesta1

Una forma de obtener un archivo Csv adecuado es ajustar el resultado de mi comentario:

Get-ChildItem -Recurse -Name -File | 
  ForEach-Object -begin {'"RelativePath"'}{'"{0}"' -f $_}|
    Out-File "test.csv"

O utilice una propiedad calculada para eliminar el directorio inicial de la FullNamepropiedad.

$StartDir = "$ENV:USERPROFILE\Documents\"
Get-ChildItem -Path $StartDir -File -Recurse |
  Select-Object @{n='RelativePath';e={$_.FullName -replace [regex]::escape($StartDir)}}|
    Export-Csv 'test.csv' -NoTypeInformation

Respuesta2

Esta pregunta se traduce en la impresión de que eres muy nuevo en PowerShell. Por lo tanto, es vital que lo intensifiques para limitar/evitar conceptos erróneos, malos hábitos, errores y frustraciones graves que seguramente encontrarás. Acceda al canal 9 de YouTube/MSDN y busque PowerShell inicial, intermedio y avanzado, así como administración del sistema de archivos PowerShell y administración de archivos y carpetas PowerShell.

PowerShell, en muchos casos, intentará forzar las cosas, pero no intentará descubrir lo que usted quiere hacer. Tienes que decirle qué hacer. Bueno, esto es válido para cualquier lenguaje informático.

Tu problema aquí es lo que dices...

(relativo a la raíz desde donde ejecuto el comando)

... bueno, podrías estar en una ruta que tiene un nivel X de profundidad desde la unidad raíz, entonces, ahora estás en un niño, y la extrapolación es que quieres esto solo del niño. Aquí está el problema con ese proceso de pensamiento.

Guarde esto en un archivo de texto, luego nunca tendrá la ruta de la unidad y, como tal, cuando vuelva a usarlo, tendrá que saberlo y volver a ingresarlo manualmente para poder usar los archivos nuevamente.

Entonces, no estoy seguro de cuál es el caso de uso para este esfuerzo, pero lógicamente volverá en su contra.

Entonces, digamos que estoy aquí:

Push-Location -Path 'E:\Temp'

Luego ejecutamos esto

Get-ChildItem -recurse | 
Where-Object { !$_.PSIsContainer } | Select-Object -Property  FullName 

# Results

FullName                                                            
--------                                                            
E:\Temp\about_ReGet-ChildItemection  Microsoft Docs.url                       
...                                     
E:\Temp\ZipMultiFolder.zip                                          
E:\Temp\Folder\Log_20190419.txt                                     
...                               
E:\Temp\Reports\NewFiles.zip                                        
...  

Entonces, aquí solo obtenemos la ubicación actual...

Get-ChildItem -recurse | 
Where-Object { !$_.PSIsContainer } | 
Select-Object -Property  @{Name = 'RelativePath';Expression = {"\$($pwd.Drive.CurrentLocation)\$($PSItem.Name)"}}

Entonces, aquí solo obtenemos la ruta actual en la que nos encontramos y solo solicitamos el nombre del archivo, no el nombre completo.

# Results

RelativePath 
------------                                                            
\Temp\about_ReGet-ChildItemection  Microsoft Docs.url                       
...                                     
\Temp\ZipMultiFolder.zip                                          
\Temp\Folder\Log_20190419.txt                                     
...                               
\Temp\Reports\NewFiles.zip                                        
... 

Si enviamos esto a un CSV, no tendrá idea de qué unidad proviene. Entonces, ahora debe buscar en cada unidad de su máquina para encontrarlas o recordar dónde estaba cuando hizo esto.

Bajar a un niño, lo mismo. Seguro que entiendes esto, pero ¿dónde está realmente? En su sistema o en alguna unidad de red que haya asignado.

Push-Location -Path 'E:\Temp\Folder'

Luego ejecutamos esto

Get-ChildItem -recurse | 
Where-Object { !$_.PSIsContainer } | Select-Object -Property  FullName 

# Results

FullName                                   
--------                                   
E:\Temp\Folder\Log_20190419.txt            
E:\Temp\Folder\New Bitmap Image.bmp        
E:\Temp\Folder\New Text Document - Copy.txt
E:\Temp\Folder\New Text Document.txt  


Get-ChildItem -recurse | 
Where-Object { !$_.PSIsContainer } | 
Select-Object -Property  @{Name = 'RelativePath';Expression = {"\$($pwd.Drive.CurrentLocation)\$($PSItem.Name)"}}


RelativePath                             
------------                             
\Temp\Folder\Log_20190419.txt            
\Temp\Folder\New Bitmap Image.bmp        
\Temp\Folder\New Text Document - Copy.txt
\Temp\Folder\New Text Document.txt  

Y si estás diciendo que no quieres la raíz principal, entonces la eliminas.

Sin embargo, eso significa que no sólo no sabes de qué unidad proviene, sino que tampoco sabes de qué unidad raíz proviene.

Entonces, solo dilo.

Por cierto, se recomienda utilizar el nombre completo del cmdlet en los scripts. La taquigrafía/alias están bien para cosas interactivas. Claro, todos estamos acostumbrados a usar 'dir', pero la abreviatura que obtuvo Get-ChildItem es 'gci', que es tan corta como lo hizo, pero, ya sabes.

Get-Alias -Definition Get-ChildItem | 
Format-Table -AutoSize



CommandType Name                 Version Source
----------- ----                 ------- ------
Alias       dir -> Get-ChildItem               
Alias       gci -> Get-ChildItem               
Alias       ls -> Get-ChildItem  

Pero bueno, los hábitos son realmente difíciles de romper. ;-} --- --- y las decisiones prudentes son las que nos funcionan a nosotros, independientemente de lo que piensen los demás. ;-}

Bueno, los que te siguen hacen tomar postura. Entonces, ser un buen ciudadano de PowerShell es realmente algo bueno.

Por cierto, si fueras a hacer esto en un script, también hay una variable automática para este tipo de cosas. Bueno, obtener la ubicación donde se ejecutó el script y todo lo asociado a esa ubicación.

Vea este artículo.

Agregue flexibilidad de secuencias de comandos con rutas de archivos relativas

información relacionada