Windows : Remplacer un fichier par un autre

J’ai un même fichier qui est présent dans plein de répertoires et de sous-répertoires. De temps en temps, j’aimerais le remplacer par un autre fichier avec un nom différent, dans tous les répertoires. Je suis tombé sur la commande Windows « replace » qui semble faire ce que je veux. Elle a l’air simple à mettre en œuvre mais pourtant ça marche pas quand j’essaie (le script mouline en boucle et rien ne change dans les répertoires). C’est sûr que je fais mal un truc mais quoi ? J’en suis là :

replace C:\Users\Kip\Desktop\source\sourcefile.png C:\Users\Kip\Desktop\target\filetoreplace.png /s

1 « J'aime »

Quand je regarde la doc DOS/Replace — Wikilivres

Précise l’emplacement du fichier cible. Vous ne pouvez pas spécifier le nom des fichiers de remplacement.

Il faudrait que tu précises ce que tu veux faire. En attendant jete un coup d’œil à ce lien

https://www.malekal.com/comment-copier-des-fichiers-en-invite-de-commandes-cmd/

Tu veux un script python ? (Ça me semble plus facile que CMD :sweat_smile:)

:sweat_smile: J’y ai pensé mais je l’ai gardé pour moi.

Autant que possible que ça soit une solution standard surtout si sa demande est simple (à vérifier).

Ah oui je comprend mieux. Du coup la commande replace est peut-être pas celle qu’il me faut. J’ai lu ton lien mais j’ai pas l’impression d’avoir trouvé la bonne manip pour mon souci. Ce que je veux faire en détails :

  • J’ai un fichier nommé file-v1.pdf qui se trouve à plusieurs endroits dans une arborescence de dossiers.
  • J’ai le même fichier file-v1.pdf dans un autre endroit du PC, que je modifie quelques fois par an. A chaque modification, je l’incrémente de 1, il devient donc pour l’exemple : file-v2.pdf
  • Je dois ensuite remplacer le vieux fichier file-v1.pdf par le nouveau file-v2.pdf dans tous les dossiers de l’arborescence. Donc forcement, à la main c’est chiant.

Je pensais que la commande replace allait me permettre de cibler tous les fichiers file-v1.pdf de l’arborescence et de lui dire : "remplace-les tous par file-v2.pdf".

Apparemment non !

Et voila. A tester.

import os
import shutil
from os import listdir
from os.path import join

directory = "/path/to/directory"
sourcefileName = "test.txt"
newFilePath ="/path/to/file/filename.png"

if __name__=='__main__':
    data = [x[0] for x in os.walk(directory) if x[0]!='.' and sourcefileName in listdir(x[0])]
    for i in data:
        os.remove(join(i,sourcefileName))
        shutil.copyFile(newFilePath,i)

Ah ben non :slight_smile:

Donc effectivement ce n’est pas si simple et il faudrait utiliser le script d’@Ewi (ou un similaire si tu veux utiliser un autre langage de script).

Ouais… Je m’attendais pas à aussi compliqué :smiley: Merci !

J’ai testé et le script semble fonctionner à moitié :

  • Il supprime le fichier à remplacer mais il ne met pas le nouveau à la place
  • Il ne prend pas en compte les sous répertoires (le fichier à remplacer se trouve à plein d’endroits différents dans l’arborescence de dossiers)

Juste pour être sûr, voilà le code en reprenant les noms de fichiers de mon exemple (je me suis peut-être planté) :

import os
import shutil
from os import listdir
from os.path import join

directory = "/path/to/directory" # L’arborescence de dossiers
sourcefileName = "file-v1.pdf" # L'ancien fichier à remplacer dans l’arborescence
newFilePath ="/path/to/file/file-v2.pdf" # Le nouveau fichier qui doit remplacer l'ancien

if __name__=='__main__':
    data = [x[0] for x in os.walk(directory) if x[0]!='.' and sourcefileName in listdir(x[0])]
    for i in data:
        os.remove(join(i,sourcefileName))
        shutil.copyFile(newFilePath,i)

Ici , il faut le chemin complet vers file-v2.pdf pour que ça marche

et ptite coquille sur un nom de fonction avec un exemple de paramètre:

import os
import shutil
from os import listdir
from os.path import join

directory = "C:\Users\Kip\Dossier\"
sourcefileName = "file-v1.pdf"
newFilePath ="C:\Users\Kip\Desktop\target\file-v2.pdf"

if __name__=='__main__':
    data = [x[0] for x in os.walk(directory) if x[0]!='.' and sourcefileName in listdir(x[0])]
    for i in data:
        print("fichier modifié dans :",i)
        os.remove(join(i,sourcefileName))
        shutil.copy(newFilePath,i)

Oui bien sûr, c’est ce que j’ai fait dans le script. J’ai juste oublié de modifier ton code dans mon exemple !

Edit. Je viens de voir ta réponse, je reteste.

Génial, ça marche merci ! J’ai beau regarder, je vois pas la coquille… C’est juste le print ?

sur la fonction pour copier :

shutil.copyFile(newFilePath,i) -> shutil.copy(newFilePath,i)

Tu peux enlever le print, il sert pas a grand chose.

Ok vu. Sinon juste par curiosité, c’est possible d’arriver à la même chose avec des commandes Windows ? Ou il faut obligatoirement utiliser un langage dédié comme Python ?

Surement mais je ne connais pas bien. C’est même peut-être plus simple en powershell.

Ok, merci encore !

Install linux…
.
.
.
.
oh, ça va, je déconne hein :slight_smile: mais en shell ca peut se faire comme ça (ca marche sur le sous-systeme bash s’il est installé sur ton windows)

find /path/to/directory -type f -name file-v1.pdf -exec cp -pr /path/to/file/file-v2.pdf {} \;

(j’ai pas compris si le nouveau fichier, outre son contenu, devait avoir le nouveau nom où si c’est juste le contenu qui est changé. J’ai fait le 2eme choix)

Pas con :slight_smile: avec -f pour être sûr que le remplacement se fait bien en cas « d’homonymie » ?

Non, juste pour être sûr que c’est bien un fichier et pas un dossier avec le même nom…
Edit, j’avais pas vu la modif en fait que tu avais faite et je croyais que tu parlais du find, sorry

on est d’accord que tu veux remplacer le contenu des tous les sourcefile.png
par le contenu du fichier filetoreplace.png ?

la commande est:
replace "C:\Users\Kip\Desktop\source\sourcefile.png" "C:\Users\Kip\Desktop\target" /s

il va chercher tous les fichiers sourcefile.png dans les sous répertoires de « C:\Users\Kip\Desktop\target » et les remplacer par le contenu de « C:\Users\Kip\Desktop\source\sourcefile.png »