Rajouter date après premier espace dans noms de fichiers

Rajouter date après premier espace dans noms de fichiers - Shell/Batch - Programmation

Marsh Posté le 10-06-2022 à 17:20:29    

Bonjour,
 
Je voudrais changer par batch avec Powershell le nom de tous les fichiers d'un dossier pour y rajouter la date de création juste après le premier espace, quel que soit le nombre de caractères qui précèdent.
Voici un exemple qui sert à rajouter la date de modification à la fin d'un nom ;

Code :
  1. get-childitem -Path "F:\ab" | ForEach-Object {$_ | Rename-Item -NewName {$_.Basename + ' ' + ("{0:yyyy-MM-dd HH\hmm}" -f $_.LastWriteTime) + $_.Extension }}


Il faut peut-être utiliser la fonction -replace pour remplacer le premier espace par un espace suivi de la date mais je ne sais pas comment désigner le premier espace.
 
exemples ;
agrafe d12 fd3.txt => agrafe 2007 08 06 d12 fd3.txt
hello my dear friend.txt => hello 2012 04 23 my dear friend.txt
 
J'ai trouvé cet exemple similaire pour remplacer le dernier espace par une virgule mais j'ai du mal à le comprendre ;
https://www.reddit.com/r/PowerShell [...] ith_comma/
 

Code :
  1. function Replace-LastSubstring {
  2. param(
  3.     [string]$str,
  4.     [string]$substr,
  5.     [string]$newstr
  6. )
  7. return $str.Remove(($lastIndex = $str.LastIndexOf($substr)),$substr.Length).Insert($lastIndex,$newstr)
  8. }


 
 :jap:

Reply

Marsh Posté le 10-06-2022 à 17:20:29   

Reply

Marsh Posté le 10-06-2022 à 19:55:50    

Il y a aussi cette idée qui est pas mal mais je ne parviens pas à l'adapter à mon cas ;
https://stackoverflow.com/questions [...] n-a-string
Il remplace le premier name avec les options pattern et pattern.replace qui permet de stipuler le nombre de fois que le pattern sera remplacé (ici 1 donc seul le premier name est remplacé) ;

Code :
  1. $test = "My name is Bob, her name is Sara."
  2. [regex]$pattern = "name"
  3. $pattern.replace($test, "baby", 1)
  4. > My baby is Bob, her name is Sara


 
Ou là, il remplace le premier point par du vide (ce qui revient à effacer le point) ;
https://stackoverflow.com/questions [...] ect=1&lq=1
 
J'essaye d'adapter ça à mon script pour remplacer le premier espace mais ça ne marche pas, sans doute une erreur de syntaxe ;

Code :
  1. get-childitem -Path "K:\test" | ForEach-Object {$_ | Rename-Item -NewName {$_.name -pattern = " " -pattern.replace("' ' + ("{0:yy MM dd HH}" -f $_.CreationTime) + ' '", 1)}}


Message édité par arnuche le 10-06-2022 à 20:11:04
Reply

Marsh Posté le 11-06-2022 à 14:23:39    

Un truc comme ça ?

Code :
  1. [regex]$pattern = "\s"
  2. Get-Childitem -Path "K:\test" | ForEach-Object { $_ | Rename-Item -NewName ($pattern.replace((" {0:yy MM dd HH} " -f $_.CreationTime), 1))}


Message édité par Je@nb le 12-06-2022 à 19:34:00
Reply

Marsh Posté le 11-06-2022 à 19:00:53    

Merci, alors là il m'a fait un truc bizarre ; il a remplacé tout le nom du fichier et l'extension par une suite de 13 chiffres qui ne correspond pas à la date, et sans espace entre les chiffres  :heink:  
 
Et j'ai réalisé qu'il me faudrait un espace devant et un derrière la date, donc pas juste remplacer le 1er espace par la date.
 
En continuant mes recherches, j'ai vu qu'il y avait aussi moyen d'utiliser la fonction split : dans ce cas on ne procède plus par remplacement mais on renomme le fichier en gardant le premier mot et un espace, puis on rajoute la date, puis un espace, puis le reste du nom d'origine et enfin l'extension.
Si on se réfère à mon premier script, il faudrait remplacer $_.Basename, ce qui donnerait un truc de ce genre ;

Code :
  1. get-childitem -Path "F:\ab" | ForEach-Object {$_ | Rename-Item -NewName {$_.mot1 + ' ' + ("{0:yyyy-MM-dd HH\hmm}" -f $_.LastWriteTime) + ' ' + $_.fin de nom + $_.Extension }}


Ce serait la fin du script, il faudrait commencer par définir ce qui correspond à "mot1" (tous les signes qui précèdent le 1er espace) et la "fin de nom" (tout ce qui suit le 1er espace) pour pouvoir les remettre avec la fonction NewName.
 
Ou alors on reste sur l'idée du remplacement mais je ne sais pas si on peut remplacer un caractère (ici un espace) par un espace + la date + encore un espace.


Message édité par arnuche le 11-06-2022 à 19:05:51
Reply

Marsh Posté le 12-06-2022 à 19:34:05    

My bad j'ai oublié le plus important :D

 
Code :
  1. [regex]$pattern = "\s"
  2. Get-Childitem -Path "K:\test" | ForEach-Object { $_ | Rename-Item -NewName ($pattern.replace($_ , (" {0:yy MM dd HH} " -f $_.CreationTime), 1))}


Message édité par Je@nb le 13-06-2022 à 10:03:07
Reply

Marsh Posté le 12-06-2022 à 22:15:28    

Excellent, ça marche, merci beaucoup  :)  :jap:  
 
Je l'ai modifié pour rajouter les minutes et les secondes (avec aussi un h et un m) ;

Code :
  1. [regex]$pattern = "\s"
  2. Get-Childitem -Path "K:\test" | ForEach-Object { $_ | Rename-Item -NewName ($pattern.replace($_ , (" {0:yy MM dd HH}" -f $_.CreationTime) + 'h' + ("{0:mm}" -f $_.CreationTime) + 'm' + ("{0:ss} " -f $_.CreationTime), 1))}


Noter l'espace supprimé derrière HH} et celui rajouté derrière ss}.
Ce qui transforme par exemple ;
bouquins liste 2b.txt
en
bouquins 18 03 28 16h52m41 liste 2b.txt
 
Une fois qu'on a le truc ça va tout seul, exemple ; si on veut les années sur 4 chiffres on remplace yy par yyyy.

Reply

Marsh Posté le 12-06-2022 à 23:50:27    

C'est dégueu putain  :lol:
Suis pas sur l'ordi pour tester mais ya bcp plus simple

Reply

Marsh Posté le 13-06-2022 à 00:29:21    

Ah, ben je veux bien plus simple si tu as  ;)

Reply

Marsh Posté le 13-06-2022 à 10:03:12    


Code :
  1. [regex]$pattern = "\s"
  2. Get-Childitem -Path "K:\test" | ForEach-Object { $_ | Rename-Item -NewName ($pattern.replace($_ , (" {0:yy MM dd HH'h'mm'm'ss's'} " -f $_.CreationTime), 1))}


C'est pas mieux ? :D

Reply

Marsh Posté le 13-06-2022 à 10:18:50    

Ah oui, je ne savais pas qu'on pouvait rajouter des caractères entourés d'apostrophes entre les accolades  :jap:


Message édité par arnuche le 13-06-2022 à 10:19:01
Reply

Marsh Posté le 13-06-2022 à 10:18:50   

Reply

Marsh Posté le 13-06-2022 à 10:44:53    

Après il y a d'autres possibilités en mettant directement :
$_.CreationTime.ToString(" yy MM dd HH'h'mm'm'ss's' " ) pour éviter le format mais c'est kifkif

Reply

Marsh Posté le 13-06-2022 à 10:53:27    

Ok je note, avec un peu d'imagination on peut faire beaucoup de choses avec Powershell.


Message édité par arnuche le 13-06-2022 à 10:53:47
Reply

Marsh Posté le 15-06-2022 à 10:44:27    

J'ai encore trouvé quelques fonctions sympa mais je bute sur un problème : comment faire pour modifier une suite de 6 chiffres dans des noms de fichiers (sachant que le nombre de caractères qui précède et qui suit est variable) pour y rajouter 2 caractères, c'est en fait l'heure et j'aimerais y rajouter un h et un m pour plus de clarté ;
081254 => 08h12m54
 
 :jap:


Message édité par arnuche le 15-06-2022 à 10:45:01
Reply

Marsh Posté le 15-06-2022 à 11:37:14    

Code :
  1. "coucou 123456 tata" -replace '(\d{2})(\d{2})(\d{2})','$1h$2m$3'

par exemple ?

Reply

Marsh Posté le 15-06-2022 à 12:08:56    

Je ne sais pas, on fait comment pour adapter ça à un batch ?
Parce que j'ai des centaines de fichiers à renommer qui ont tous des noms différents donc il faut pouvoir cibler la suite de 6 chiffres quels que soient les autres caractères.

Reply

Marsh Posté le 15-06-2022 à 13:08:39    

bah comme plus haut

Reply

Marsh Posté le 15-06-2022 à 14:32:43    

Ah ok, sans regex, en effet ;

Code :
  1. Get-Childitem -Path "K:\test" | ForEach-Object { $_ | Rename-Item -NewName {$_.name -replace '(\d{2})(\d{2})(\d{2})', '$1h$2m$3' }}


Astucieux !  :jap:

Reply

Marsh Posté le 15-06-2022 à 15:10:37    

C'est une regex en fait juste que la je l'ai appelée plus simplement. On peut faire pareil avec le premier besoin

Reply

Marsh Posté le 15-06-2022 à 15:18:49    

Ah d'accord, j'ai encore beaucoup à apprendre !

Reply

Marsh Posté le 18-06-2022 à 14:07:15    

Hello,
j'ai pensé à un truc : y a-t-il moyen d'utiliser 2 pattern dans la même commande ?
Par exemple pour faire comme plus haut (remplacer le 1er espace par une date) et en même temps (comme dirait l'autre) remplacer un mot (plus loin dans le nom du fichier) par un autre ?

Reply

Marsh Posté le 18-06-2022 à 15:25:39    

Sûrement, la seule limite est l'imagination :D

Reply

Marsh Posté le 19-06-2022 à 02:08:14    

J'en ai mais vu mes connaissances limitées en syntaxe de PS, je ne trouve rien qui marche.
J'ai tenté ça à tout hasard, pas de message d'erreur mais seul le 1er pattern est pris en compte ;

Code :
  1. [regex]$pattern1 = "\s"
  2. [regex]$pattern2 = "chemise"
  3. Get-Childitem -Path "K:\test" | ForEach-Object { $_ | Rename-Item -NewName ($pattern1.replace($_ , " Jimi ", 1))} | ForEach-Object { $_ | Rename-Item -NewName ($pattern2.replace($_ , "tetra", 1))}


 
pareil comme ça (différence au niveau des accolades) ;

Code :
  1. [regex]$pattern1 = "\s"
  2. [regex]$pattern2 = "chemise"
  3. Get-Childitem -Path "K:\test" | ForEach-Object { $_ | Rename-Item -NewName ($pattern1.replace($_ , " Jimi ", 1)) | ForEach-Object { $_ | Rename-Item -NewName ($pattern2.replace($_ , "tetra", 1))}}


 
Par contre si je fais ça c'est le 2ème pattern qui est modifié et pas le 1er  :heink:  ;

Code :
  1. [regex]$pattern1 = "\s"
  2. [regex]$pattern2 = "chemise"
  3. Get-Childitem -Path "K:\test" | ForEach-Object { $_ | Rename-Item -NewName ($pattern1.replace($_ , " Jimi ", 1))}, { $_ | Rename-Item -NewName ($pattern2.replace($_ , "tetra", 1))}


Message édité par arnuche le 19-06-2022 à 14:20:55
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed