web-dev-qa-db-fra.com

Forfiles Batch Script (Caractère d'échappement @)

Je travaille sur un script batch qui me permet de supprimer des fichiers plus anciens qu'une période définie à l'aide de forfiles . Pour l'instant, je vise à imprimer les fichiers qui seront supprimés.

L’invocation forfiles que j’utilise fonctionne parfaitement à partir d’un shell cmd.exe, mais dès que je l’intègre dans un script batch, elle se termine. Je soupçonne que cela est dû au caractère @ qui ne s’échappe pas correctement, mais je ne suis pas certain.

La commande que je lance est la suivante:

forfiles /S /P "r:\" /m *.bak /d -10 /c "cmd /c echo @PATH"

Et il en résulte l'erreur suivante:

ERROR: Invalid argument/option - '@PATH'
Type "FORFILES /?" for usage.

J'ai cherché sur Google et essayé différentes méthodes pour échapper au composant @PATH. Tout de @@ PATH , à\"@ PATH \" sans résultat. 

Toute aide serait appréciée!

Je dois aussi noter que je me base beaucoup sur mes connaissances des fichiers de/à partir de ici.

16
Paradox

J'ai eu le même problème jusqu'à ce que j'ai supprimé les guillemets autour du chemin du répertoire, comme ceci:

forfiles /S /P r:\ /m *.bak /d -10 /c "cmd /c echo @PATH"

J'espère que cela pourra aider.

38
user61470

Essayez de couper le \ final à partir de votre chemin /P. Vous devriez ensuite pouvoir utiliser des guillemets pour encapsuler un chemin comportant un espace.

17
lolquotes

C'est une vieille question, mais j'ai une réponse différente ... au cas où quelqu'un en aurait besoin.

Lors de l'utilisation de 'forfiles', le chemin (écrit après/p) PEUT être entre guillemets. Cependant, cela ne doit pas se terminer par un slash.

Si vous voulez exécuter 'forfiles' pour le répertoire racine d'un lecteur:
forfiles /p "C:" /c "cmd /c echo @file"

Si vous souhaitez traiter des fichiers dans un autre répertoire ...
forfiles /p "C:\Program Files" /c "cmd /c echo @file"

En d'autres termes, l'approche la plus sûre consiste à:

  • Utilisez toujours des guillemets (car les dossiers avec des espaces, comme 'Program Files', continueront de fonctionner)
  • Toujours omettre la dernière barre oblique

forfiles /p "C:\Path\Without\Trailing\Slash"

2
hbCyber

Mettez forfiles.exe pour que tout fonctionne correctement, sinon le @variables ne sera pas transmis lorsque vous utilisez un fichier de traitement par lots. Forfiles fonctionnera si vous êtes à l'invite de commande, mais lorsque vous l'exécutez dans un fichier de commandes, les variables ne fonctionnent pas correctement, à moins que vous ne mettiez: forfiles.exe.

Voici un exemple qui supprime certains fichiers txt de plus de 30 jours forfiles.exe /P c:\directory\ /M *.txt /C "cmd /c del @path" /d -30

0
Ron Veillon

La meilleure pratique consiste à utiliser des guillemets doubles autour du paramètre de chemin (/ P) pour gérer les chemins comportant des espaces. 

Le problème se produit lorsque la substitution varialble contient une barre oblique inverse de fin. La barre oblique inverse "échappe" à la citation, ce qui amène FORFILES à interpréter de manière erronée le reste de la ligne de commande.

Par convention, le chemin d'accès à un répertoire n'a pas besoin de la barre oblique inverse finale, la seule exception étant le répertoire racine. Spécifier uniquement la lettre du lecteur et un signe deux-points C: ne fait PAS référence à la racine, mais au "répertoire en cours" de ce lecteur. Pour faire référence à la racine, il faut utiliser la barre oblique inversée C:\.

Ma solution est la suivante:

Lorsque vous utilisez FORFILES, ajoutez un . avant la fermeture "du paramètre /P, par ex.

FORFILES /P "%somePath%." /C "CMD /C ECHO @path"

Après substitution, cela conduit à des chemins de la forme C:\., C:\TEMP. ou C:\TEMP\.. Tous ces éléments sont traités correctement par FORFILES et également par DIR.

Je n'ai pas testé toutes les variables de substitution possibles pour FORFILES, être @path ne semble pas être affecté par l'ajout du .

0
andyb

J'ai trouvé qu'il existe deux versions de FORFILES, l'une est la version 1998 (merci à Emmanuel Boersma) et l'autre est la version 2005 (la date et l'heure modifiées le montrent).

FORFILES v 1.1 - by Emmanuel Boersma - 4/98

Syntax : FORFILES [-pPath] [-mSearch Mask] [-ccommand] [-dDDMMYY] [-s]

 -pPath             Path where to start searching
 -mSearch Mask      Search files according to <Search Mask>
 -cCommand          Command to execute on each file(s)
 -d[+|-][DDMMYY|DD] Select files with date >= or <=DDMMYY (UTC)
                    or files having date >= or <= (current date - DD days)
 -s                 Recurse directories
 -v                 Verbose mode

The following variables can be used in Command :
 @FILE, @PATH, @RELPATH, @ISDIR, @FSIZE, @FDATE, @FTIME

Default : <Directory : .> <Search Mask : *.*>  <Command : "CMD /C Echo @FILE">
Examples :
FORFILES -pc:\ -s -m*.BAT -c"CMD /C Echo @FILE is a batch file"
FORFILES -pc:\ -s -m*.* -c"CMD /C if @ISDIR==TRUE echo @FILE is a directory"
FORFILES -pc:\ -s -m*.* -d-100 -c"CMD /C Echo @FILE : date >= 100 days"
FORFILES -pc:\ -s -m*.* -d-010193 -c"CMD /C Echo @FILE is quite old!"

Chaque version a sa syntaxe unique.

FORFILES [/P pathname] [/M searchmask] [/S]
         [/C command] [/D [+ | -] {MM/dd/yyyy | dd}]

Description:
    Selects a file (or set of files) and executes a
    command on that file. This is helpful for batch jobs.

Parameter List:
    /P    pathname      Indicates the path to start searching.
                        The default folder is the current working
                        directory (.).

    /M    searchmask    Searches files according to a searchmask.
                        The default searchmask is '*' .

    /S                  Instructs forfiles to recurse into
                        subdirectories. Like "DIR /S".

    /C    command       Indicates the command to execute for each file.
                        Command strings should be wrapped in double
                        quotes.

                        The default command is "cmd /c echo @file".

                        The following variables can be used in the
                        command string:
                        @file    - returns the name of the file.
                        @fname   - returns the file name without
                                   extension.
                        @ext     - returns only the extension of the
                                   file.
                        @path    - returns the full path of the file.
                        @relpath - returns the relative path of the
                                   file.
                        @isdir   - returns "TRUE" if a file type is
                                   a directory, and "FALSE" for files.
                        @fsize   - returns the size of the file in
                                   bytes.
                        @fdate   - returns the last modified date of the
                                   file.
                        @ftime   - returns the last modified time of the
                                   file.

                        To include special characters in the command
                        line, use the hexadecimal code for the character
                        in 0xHH format (ex. 0x09 for tab). Internal
                        CMD.exe commands should be preceded with
                        "cmd /c".

    /D    date          Selects files with a last modified date greater
                        than or equal to (+), or less than or equal to
                        (-), the specified date using the
                        "MM/dd/yyyy" format; or selects files with a
                        last modified date greater than or equal to (+)
                        the current date plus "dd" days, or less than or
                        equal to (-) the current date minus "dd" days. A
                        valid "dd" number of days can be any number in
                        the range of 0 - 32768.
                        "+" is taken as default sign if not specified.

    /?                  Displays this help message.

Examples:
    FORFILES /?
    FORFILES
    FORFILES /P C:\WINDOWS /S /M DNS*.*
    FORFILES /S /M *.txt /C "cmd /c type @file | more"
    FORFILES /P C:\ /S /M *.bat
    FORFILES /D -30 /M *.exe
             /C "cmd /c echo @path 0x09 was changed 30 days ago"
    FORFILES /D 01/01/2001
             /C "cmd /c echo @fname is new since Jan 1st 2001"
    FORFILES /D +3/19/2012 /C "cmd /c echo @fname is new today"
    FORFILES /M *.exe /D +1
    FORFILES /S /M *.doc /C "cmd /c echo @fsize"
    FORFILES /M *.txt /C "cmd /c if @isdir==FALSE notepad.exe @file"

Passez un bon moment en rendant "Batch File" plus sophistiqué. :)

0
Rhak Kahr

DID NOT WORK

FORFILES /P %deletepath% /M *.%extension% /D -%days% /C "cmd /c del @PATH"

DID WORK

FORFILES /P %deletepath% /M *.%extension% /D -%days% /C "cmd /c del @path"

@path fonctionne en minuscule.

Après avoir cherché partout, je suis tombé sur la réponse lors de mes propres tests. En utilisant la dernière version sur le serveur 2012 R2, j'ai essayé de changer le @PATH en minuscule. Cela a résolu le problème pour moi.

Bonne chance!

0
Vj Prasad
dir *.* > C:\path\dummy%date:~4,2%%date:~7,2%%date:~10,4%.DAT

dir *.* > C:\path\dummy%date:~4,2%%date:~7,2%%date:~10,4%.csv

forfiles -p C:\path\ -m *.DAT /d -50 /c "cmd /c del /Q @path"
forfiles -p C:\path\ -m *.csv /d -50 /c "cmd /c del /Q @path"
  1. Remplacez les fichiers .dat et .csv que vous voulez supprimer.

  2. -50 supprimer les plus vieux puis les 50 jours

  3. Ceci est le fichier batch Windows

0
Raju Mella