Windows : Remplacer un fichier par un autre

Je vois que c’est écrit vraiment différemment par rapport au script de @Ewi et @Sarbian. Ce n’est pas la même chose ? Pour rappel (au passage, le script ne marche pas) :

$dir = 'c:\path\to\dir'
$newFile = 'c:\path\to\file'
$oldName = "fileV2.pdf"
$files = Get-ChildItem -Path $dir -Recurse -Filter $oldName -File
$files | ForEach-Object {    
 Write-Host 'Replacing:'$_.FullName
 Copy-Item -Path $newFile -Destination $_.FullName -Force 
}

Non. Eux ont fait du Powershell… qui nécessite Windows PowerShell (-qui est dans Windows 10)
Là c’est du .bat le truc le plus basique qui vient de ms-dos et fonctionne sur presque tous les windows de base.

ouais enfin fait du bat en 2021, faut vraiment aimer la necrophilie :smiley: Powershell est le successeur du shell de msdos, si tu veux faire un truc directement dans l’OS, c’est ca qu’il faut utiliser.

Sinon Python c’est très bien :slight_smile:

Super. Osef. Ca marche. Ca prend pas plus de temps.
Si c’est pour recommander python hein, tu aurais pu t’abstenir.

Le script de Ewi en Python marche effectivement super bien. Mais j’ai cru comprendre qu’au fil des années, quelques subtilités peuvent changer et certains scripts ne marchent plus. Par exemple, Stackoverflow est rempli de ce genre de petits scripts inutilisables sans une mise à jour du code, donc pour un mec qui moi qui code pas, ça peut devenir compliqué.

D’où ma question sur la faisabilité sans rien installer, directement dans Windows. D’ailleurs @AnA-l, pour OLD_FILE et NEW_FILE, il faut évidemment mettre le chemin en entier (C:/etc…) ?

C’est un peu plus compliqué pour le python : si tu le package bien avec un bon environnement indépendant, y aura pas le problème.

Par contre, c’est pas natif et la solution powershell sera de toute façon plus simple à mettre en place si tu changes de PC tant que tu restes sur Windows.

La solution sh de @SkullyFM a le mérite de marcher même si tu passes sur Mac ou Linux :wink:

1 « J'aime »

Le python, ya eu une mise a jour (2.7->3) qui a peté pas mal de trucs ouais, mais ca devrait se tasser quand meme avec le temps. Perso, je trouve ca clairement overkill pour copier/delete un fichier dans une arborescence, mais ca fait le taff. Tu as 40 moyens de le faire dans a peu pres chacun des langages qui existent. C’est pas pour autant que c’est l’idéal.

Pour te repondre sur le bout que je t’ai filé, c’est comme tu veux, ca depend d’ou son tes fichiers a la base. La je les avais mis dans BASE_PATH our tester, mais si ils sont ailleurs, faut adapter la concatenation des variables. (Et comme il a dit @nusul, ajouter des " " autour des valeurs passés en arguments a copy, histoire de pas avoir de surprises avec les paths contenant des espaces).

Et alors? sous prétexte que c’est ancien c’est inutile?
Si tu peux faire ce dont tu as besoin, tu peux utiliser ce que tu veux! il n’existe pas de

En informatique si on peut faire autrement.

Et autant recommander d’apprendre maintenant le powershell, plutot que le batch, c’est une bonne idée car plus puissant, et est désormais présent dans tous les windows.

à t’ecouter on aurait tous du faire du vbscript à une époque… :slight_smile:

Autant le python qui nécessite une installation moins.

2 « J'aime »

Non j’ai recommandé powershell. Et si c’est pour fournir un bash qui marche pas, tu aurais pu t’abstenir aussi …

@nusul : bien sur qu’on peut utiliser ce qu’on veut :slight_smile: Si tu tronques ma phrase, tu me fais dire ce que tu veux. J’ai écris « si tu veux faire directement dans l’OS » → Donc tant qu’a apprendre à faire du shell, autant le faire avec les outils de 2021. Et le shell sous windows en 2021, c’est powershell, pas msdos … D’ou ma remarque sur la nécrophilie.
En fait, t’avais juste qu’à lire ma phrase pour comprendre ce que je voulais dire :innocent:

non non je la re-dis: c’est le fin qui me dérange, l’aspect « vous devez faire ca, point » :slight_smile:
Un néophyte peut la croire et la prendre tel quel

1 « J'aime »

Je déteste le shell de msdos mais si on veut répondre à la question de @Kip de vouloir quelque chose d’immuable le shell de msdos est le plus approprié dans le monde Windows et donc la réponse de @AnA-l est à mon avis dans cette optique là la plus appropriée.

:slight_smile:

Qu’ @AnA-l ait fait des petites erreurs dans son script n’est pas grave : @Kip doit un minimum le comprendre et le tester pour l’installer surtout s’il y a de la suppression potentiellement massive à la clé.

Les autres réponses ça lui servira plutôt à "si le cœur t’en dit tu peux aussi le faire en Power Shell ou en Bash ou en Python ". Et pourtant au niveau amusement je préfère nettement ces solutions surtout les deux dernières.

Mais dans beaucoup d’entreprises tu n’as pas la dernière version de Windows et son script peut être déplacé d’un ordi à l’autre. Récemment j’ai fait un certain nombre de scripts Bash pour Linux Ubuntu 20 mais comme on a des vieux Windows j’ai préféré utiliser le bon vieux shell msdos pour les ordis Windows plutôt que d’installer un shell annexe ou Python, tant que ce n’est pas trop compliqué pour cet antique shell msdos.

1 « J'aime »

Bon, j’ai un peu avancé. J’ai lu la page que tu as linké sur FOR et j’ai pu modifier ton script. Déjà, j’ai supprimé %BASE_PATH% dans copy et del sinon le script ne fonctionnait pas. Pour info voilà le script qui ne marche pas avec les vrais chemins (peut-être que j’ai mal fait un truc ?) :

cls
echo off
set OLD_FILE=filetoreplace.png
set NEW_FILE=C:\Users\Kip\Desktop\source\sourcefile.png
set BASE_PATH=C:\Users\Kip\Desktop\target

For /f "tokens=*" %%G IN ('dir /b /s /a:d "%BASE_PATH%*"') do (

echo Working in %%G

echo Copying %BASE_PATH%%NEW_FILE% to %%G\%NEW_FILE%
copy %BASE_PATH%%NEW_FILE% %%G\%NEW_FILE%

echo Deleting old file : %%G\%OLD_FILE%
del %%G\%OLD_FILE%

echo.

)

pause

Et le message d’erreur :

C:\Users\Kip\Desktop>echo off
Working in C:\Users\Kip\Desktop\target
Copying C:\Users\Kip\Desktop\targetC:\Users\Kip\Desktop\source\sourcefile.png to C:\Users\Kip\Desktop\target\C:\Users\Kip\Desktop\source\sourcefile.png
C:\Users\Kip\Desktop\targetC:\Users\Kip\Desktop\source\sourcefile.png
La syntaxe du nom de fichier, de répertoire ou de volume est incorrecte.
        0 fichier(s) copié(s).
Deleting old file : C:\Users\Kip\Desktop\target\filetoreplace.png

Quoi qu’il en soit, voici le script modifié qui semble fonctionner avec les %BASE_PATH% en moins, à part qu’il ne va pas chercher dans les sous-répertoires. Pourtant d’après la doc il faut mettre /s et je vois qu’il y est dans les parenthèses… Quel serait le souci ?

cls
echo off
set OLD_FILE=filetoreplace.png
set NEW_FILE=C:\Users\Kip\Desktop\source\sourcefile.png
set BASE_PATH=C:\Users\Kip\Desktop\target

For /f "tokens=*" %%G IN ('dir /b /s /a:d "%BASE_PATH%*"') do (

echo Working in %%G

echo Copying "%NEW_FILE%" to %%G
copy "%NEW_FILE%" %%G

echo Deleting old file : %%G\"%OLD_FILE%"
del %%G\"%OLD_FILE%"

echo.

)

pause

Yeah, GG ! Le .bat c’est la vie !

En fait, vu que tu utilises des chemins absolus, effectivement, si tu concatene avec BASE_PATH, ca ne marche plus. C’est l’erreur ou l’on voit bien les 2 chemins collés.

C:\Users\Kip\Desktop\targetC:\Users\Kip\Desktop\source\sourcefile.png

Pour le for, il te manque un \ a la fin du BASE_PATH, soit dans la variable, vu que de toute facon tu ne l’utilises que la, ca ira, soit directement dans le for, entre le %BASE_PATH% et le *.

For /f "tokens=*" %%G IN ('dir /b /s /a:d "%BASE_PATH%\*"') do (
                                                      ^ ICI

Le for est un peu abscon et tatillon, ca, c’est un fait indeniable. Mais une fois maitrisé, il fait l’affaire pour les besoin simple. (Et par maitrisé, j’entends RTFM bien sur :smiley: )

Et aussi, si tu veux tester le script, met un REM devant les lignes de copy/delete, ca les commentera, et te permettra de voir ce qu’il va se passer avec les echo avant :wink:

D’ailleurs sur la ligne du delete, la concatenation est a moitié incorrecte, il vaudrait mieux mettre les guilemets AVANT le %%G pour qu’elle fonctionne avec les chemins contenant des espaces.

del "%%G\%OLD_FILE%"

En voyant les chemins collés c’est ce que je me suis dit oui !

Sinon après quelques tests, je me rend compte que ça fonctionne euh… trop bien en fait. Trop bien dans le sens « il me c/c le fichier sourcefile.png absolument partout ». Alors que j’aimerais qu’il ne le copie uniquement là où il y a le fichier filetoreplace.png. Là je me retrouve avec des sourcefile sans tous les dossiers de l’arborescence :smiley:

Il te reste à rajouter un if : If - Conditionally perform command - Windows CMD - SS64.com

La syntaxe :
IF EXIST filename command

Humm, j’ai réussi à insérer un if qui me parait logique mais le comportement ne change pas, il copie toujours le fichier dans tous les dossiers. Je ne vois pas mon erreur…

cls
echo off
set OLD_FILE=filetoreplace.png
set NEW_FILE=C:\Users\Kip\Desktop\source\sourcefile.png
set BASE_PATH=C:\Users\Kip\Desktop\target\

For /f "tokens=*" %%G IN ('dir /b /s /a:d "%BASE_PATH%*"') do (

	echo Working in %%G

	if exist "%OLD_FILE%" (

		echo Copying "%NEW_FILE%" to %%G
		copy "%NEW_FILE%" %%G

		echo Deleting old file : "%%G\%OLD_FILE%"
		del "%%G\%OLD_FILE%"

		echo.
		) else (
		echo File no found
		)
)

pause

if faut faire

if exist "%%G\%OLD_FILE"

Ah oui, ça marche mieux. En fait même en lisant la doc de for, %%G est encore un peu flou. Si j’ai bien compris, c’est une variable qui est incrémentée à chaque passage de la boucle for ? En quoi c’est nécessaire ?

Question bonus : pourquoi un . après le dernier echo ?

Je tempèrerais en disant que ça dépend si tu veux de la compatibilité ascendante ou descendante.

Si tu veux de la compatibilité descendante (autrement nommée rétrocompatibilité), le shell ms-dos est en effet approprié.
Par contre si tu veux de la compatibilité ascendante, Microsoft pousse depuis quelques années Powershell qui est installé nativement à partir de Windows 7 SP1 et Windows Server 2008 R2 SP1. Ce langage a aussi l’avantage d’être plus riche et de permettre de faire plus de choses, ce qui peut être utile en cas d’extension du champ d’application du script.
Le shell ms-dos (qui n’est plus lié à ms dos en fait, c’est devenu un interpréteur de commandes DOS / Windows / OS2 avec une syntaxe tirée du shell ms-dos) lui est toujours là pour rétrocompatibilité, mais son support est devenu minimal et on ne sait pas trop jusqu’à quand il va rester (même si pour être honnête, ça fait 33 ans qu’il là sous une forme ou une autre, peu de chance qu’il se barre de si tôt :smiley: )

et en plus ils continuent quand meme à le faire evoluer ! :slight_smile:
C’est sur qu’on est pas dans la philosophie « faisons tables rase du passé » comme chez apple. En bien et en mal (frein à l’innovation totale)