Estoy intentando crear un script de Powershell que:
-Buscar recursivamente desde un directorio raíz
-Excluir archivos con el prefijo de nombre de archivo "aaaaMMdd" existente
-Renombrar los archivos no excluidos anteriormente con el prefijo de nombre de archivo "aaaaMMdd" según su LastWriteTime específico
Nota: idealmente, este script debería incluir todas las extensiones de tipo de archivo.
Lo he intentado yo mismo, pero parece que está por encima de mi cabeza, ya que mis intentos no van bien.
Gracias de antemano.
http://ss64.com/ps/syntax-stampme.html
#StampMe.ps1
param( [string] $fileName)
# Check the file exists
if (-not(Test-Path $fileName)) {break}
# Display the original name
"Original filename: $fileName"
$fileObj = get-item $fileName
# Get the date
$DateStamp = get-date -uformat "%Y-%m-%d@%H-%M-%S"
$extOnly = $fileObj.extension
if ($extOnly.length -eq 0) {
$nameOnly = $fileObj.Name
rename-item "$fileObj" "$nameOnly-$DateStamp"
}
else {
$nameOnly = $fileObj.Name.Replace( $fileObj.Extension,'')
rename-item "$fileName" "$nameOnly-$DateStamp$extOnly"
}
# Display the new name
"New filename: $nameOnly-$DateStamp$extOnly"
Espero cambiar la línea:
$DateStamp = get-date -uformat "%Y-%m-%d@%H-%M-%S"
Ser LastWriteTime en lugar de get-date, pero no tengo idea de cómo hacer que esto suceda.
Este código (de otra pregunta de superusuario):
Get-ChildItem "Test.pdf" | Rename-Item -newname {$_.LastWriteTime.toString("yyyyMMdd") + " Test.pdf"}
...cambia con éxito el nombre de un solo archivo, pero parece que no puedo integrarlo en el script más grande.
Con respecto a ejecutar lo anterior de forma recursiva, he probado esto (también dehttp://ss64.com/ps/syntax-stampme.html):
foreach ($file in get-ChildItem *.* -recurse) { ./StampMe.ps1 $file.name }
Lo que logra aplicar el script PS a los archivos en el directorio raíz, pero no se aplica a ningún archivo en el árbol de subcarpetas que se propaga desde el directorio raíz.
Respuesta1
Este script debería hacer exactamente lo que quieres.
- Buscar recursivamente desde un directorio raíz
- Excluir archivos con el prefijo de nombre de archivo "aaaaMMdd" existente
- Cambie el nombre de los archivos no excluidos anteriormente con el prefijo de nombre de archivo "aaaaMMdd" según su LastWriteTime específico
Advertencia: primero debes probar este script porque cambiarle el nombre podría ser peligroso. Elimine el #
frente de Rename-Item
después de haber verificado que solo se cambiará el nombre de los archivos intencionales.
Versión larga
$folder = "C:\somefolder"
$files = get-childitem -path $folder -recurse | where { -not $_.PSIsContainer }
[datetime]$dirDate = New-Object DateTime
foreach ($file In $files) {
$strDate = $file.Name.substring(0,8)
if (-Not [DateTime]::TryParseExact($strDate, "yyyyMMdd",
[System.Globalization.CultureInfo]::InvariantCulture,
[System.Globalization.DateTimeStyles]::None, [ref]$dirDate)) {
$newName = $file.lastwritetime.tostring("yyyyMMdd ") + $file.name
echo $newName
#Rename-Item -path $file.Fullname -newname $newName
}
}
Version corta
[datetime]$dirDate = New-Object DateTime
dir "C:\somefolder" -r | ? { ! $_.PSIsContainer } | % {
if ( ! [DateTime]::TryParseExact($_.Name.substring(0,8), "yyyyMMdd",
[System.Globalization.CultureInfo]::InvariantCulture,
[System.Globalization.DateTimeStyles]::None, [ref]$dirDate)) {
$newName = $_.lastwritetime.tostring("yyyyMMdd ") + $_.name
echo $newName
#Ren $_.Fullname $newName
}
}
Respuestas usadas de stackoverflow
[DateTime]::TryParseExact
para probar si los primeros 8 caracteres pueden ser una fecha válida$_.lastwritetime.tostring("yyyyMMdd ")
para formatear elúltima escrituraestampilla
Respuesta2
Estaba intentando hacer algo similar, por ejemplo, cambiar el nombre de los archivos según la hora de la última escritura. Aquí está el powershell que hace eso:
- Cambia el nombre de cualquiera/todos los archivos en el directorio actual
- Conserva las extensiones de archivos
- Nombres en formato aaaa-MM-dd HH-mm-ss (24 h)
ls | % { Rename-Item $_ -NewName ($_.LastWriteTime.ToString("yyyy-MM-dd HH-mm-ss") + ($_.extension)) }