Comment puis-je comparer les horodatages des fichiers dans un script batch?
Dans des fichiers batch DOS, la méthode de réalisation de certaines choses est quelque peu obscurci. Heureusement, il est un fantastique site de référence pour le lot de script: Simon Sheppard SS64. (Le même site a également beaucoup d'informations sur Bash.)
L'une des difficultés est de la ramification de l'exécution en se basant sur le fait qu'un répertoire est vide.
L'évidence if exist "%dir%\*.*"
ne fonctionne pas. Mais il peut être fait avec une condition d'exécution astuce:
( dir /b /a "%dir%" | findstr . ) > nul && (
echo %dir% non-empty
) || (
echo %dir% empty
)
Un autre problème délicat est de ramification selon le contenu du fichier.
De nouveau qui peut être fait comme ceci:
( fc /B "%file1%" "%file2%" | find "FC: no differences encountered" ) > nul && (
echo "%file1%" and "%file2%" are the same
) || (
echo "%file1%" and "%file2%" are different
)
Donc, ma question est:
Est-il un moyen de faire de la branche selon les horodatages des fichiers?
C'est le genre de chose que je veux:
REM *** pseudo-code!
if "%file1%" is_newer_than "%file2%" (
echo "%file1%" is newer
) else if "%file1%" is_older_than "%file2%" (
echo "%file2%" is newer
) else (
echo "%file1%" and "%file2%" are the same age
)
Grâce.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez trouver la plus récente de deux fichiers avec une seule ligne de script batch. Juste la liste des fichiers dans l'ordre de date, les plus anciens en premier, ce qui signifie que le dernier fichier de la liste doit être le fichier le plus récent. Donc, si vous enregistrez le nom de fichier à chaque fois, le nom de famille de le mettre dans votre variable sera le nouveau fichier.
Pour, exemple:
Ce qui malheureusement n'a pas à composer avec les cachets de date étant le même. Donc nous avons juste besoin de vérifier si les fichiers ont la même date et à l'heure de la première:
('DIR /B /O:D %FILE1% %FILE2%')
? Je ne comprends vraiment pas cette ligne./O:D
les met en ordre de date et/B
fait de la sortie de "nu", c'est donc uniquement les noms de fichiers et pas la taille du fichier, etc.Dave Webb soution bien qu'on va évidemment de travailler sur des fichiers dans le même répertoire.
Voici une solution qui fonctionne sur les deux fichiers.
De la première à obtenir le temps de fichier (voir Comment obtenir le fichier de la date de la dernière modification sur la ligne de commande de Windows?).
Cependant on a ensuite manuellement briser la date et l'heure dans les différents composants de depuis Cmd.exe en les comparant un aiguillon donc 2 > 10 et 10:00 > 2:00PM.
Comparer les ans, puis le mois, puis le jour, alors AM/PM, puis à l'heure, et puis, la minute et la seconde (en fait beaucoup de temps, mais je n'ai pas la minute une meilleure idée), voir le code final à la fin.
Cependant, cette solution ne fonctionnera pas si les fichiers sont dans la même minute, mais différents par le second.
Si vous êtes à ce niveau de précision, puis obtenir le filetime à l'aide de la "forfiles de la commande" (voir https://superuser.com/questions/91287/windows-7-file-properties-date-modified-how-do-you-show-seconds).
Note que "ForFiles" a une limite qu'il ne peut pas prendre un chemin avec des espaces, donc si vous avez un chemin avec des espaces, vous aurez à changer de répertoire en premier, voir forfiles - les espaces dans le chemin d'accès au dossier
De Comparaison De Code
/p
commutateur de commande. Je crois que vous avez presque un travail complet de la solution ici 🙂sérieusement, vous devriez commencer à apprendre quelque chose d'autre. Ce n'est pas une blague. DOS(cmd.exe) manque sérieusement de la date de fonctionnalités de manipulation et beaucoup plus de lacunes. Voici la prochaine meilleure alternative nativement prévu en plus de commandes DOS, vbscript
l'exécuter en ligne de commande
Bien sûr, dans les versions plus récentes de windows, vous pourriez vouloir essayer Powershell...
...
). Python peut faire tout cela, mais elle passe par le choix de la pléthore de "popen'/'sous-processus' modules. Il pourrait y avoir un mieux-encapsulé, mieux-abstraites méthode en Python, mais je ne sais pas elle.Ici une solution plus facile. En concaténant les parties de la date comme une seule chaîne de la plus importante à la moins importante, il nous suffit de faire une simple comparaison de chaîne sur le résultat.
En d'autres termes, la comparaison YYYYMMDDAMPMHHMM valeurs de donner le résultat souhaité sans avoir à titre individuel, de comparer chaque segment de la date. Cette valeur est obtenue en concaténant les différentes parties de la chaîne de date comme extraites par le deuxième commandement.
@ REM Currently supported date part delimiters are /:. and space. You may need to add more delimiters to the following line if your date format contains alternative delimiters too. If you do not do that then the parsed dates will be entirely arbitrarily structured and comparisons misbehave.
for /f "tokens=1,2,3,4,5,6 delims=/:. " %%a in ("%getfiledatestr%") do (
set temp_value=
@ REM cmd is not able to compare integers larger than 1+31 bits, so lets convert them to strings instead. The current implementation generates numeric strings much longer than 31 bit integers worth.
call :expand set %1="%%%1%%%"
@ goto :eof
if "%getfiledatestr%" equ "" set %2=""
avant@ REM Currently supported date part delimiters
...for /f "tokens=1,2,3,4,5,6 delims=/:. " %%a in ("%getfiledatestr%") do (
Pour une situation spécifique dans laquelle vous voulez faire quelque chose dans le style d'un Makefile, de l'écrasement d'un fichier de destination basé sur un fichier source que si le fichier source est plus récent, je suis venu avec cette horrible mais la méthode simple. Ce n'est qu'une option si vous n'avez pas de soins en aucune façon sur le contenu d'un fichier de destination est plus ancien que le fichier source.
Ce que ce n'est,
xcopy
ne remplace le fichier de destination si le fichier d'origine est plus récente. Si c'est pas plus récent, %%r est "0 Fichier(s) copié", de sorte que le conditionnel de commande n'est pas exécuté, et le fichier de destination n'est jamais écrasé. Si elle est plus récente, %%r "1 Fichier(s) copié", de sorte que votre fichier de destination est brièvement une copie du fichier source, puis la commande build est exécuté, pour la remplacer par une nouvelle version de ce que le fichier de destination est en fait censé être.Je devrais probablement avoir écrit un script perl.
(Remarque: vous pouvez également
xcopy
gérer la situation où le fichier de destination ne sont pas d'abord exister, par mettre un astérisque à la fin du nom de fichier de destination; si vous ne le faites pas alorsxcopy
n'est pas sûr si la destination est un nom de fichier ou le nom du dossier et il n'y a pas de drapeau à défaut de réponse de nom de fichier.)xcopy /DYLR src "dst*" | findstr /BC:"0" >nul && @echo dst is newer
ce n'est pas remplacerdst
, vérifie juste si c'est existants et nouveaux. Oui, l'astérisque est nécessaireBasé sur Wes répondre j'ai créé script de mise à jour. Les mises à jour suis trop nombreux pour les mettre en commentaires.
Ma version est ci-dessous.