2010-08-05 5 views
2

J'ai un script de traitement par lots qui doit effectuer une action sur chacun de ses arguments. Chaque argument est un nom de fichier (il n'y a pas de commutateur), et bien sûr les noms de fichiers peuvent contenir des espaces. Le script de traitement par lots est exécuté soit en faisant glisser des fichiers dans l'icône .bat dans l'Explorateur, soit en entrant les fichiers sur la ligne de commande, en incluant les arguments avec des espaces entre guillemets.Espaces dans les arguments de script par lots

Dans le script de traitement par lots, il existe des problèmes de gestion des arguments avec des espaces. Si j'utilise %* comme suit, les citations sont ignorées et chaque 'mot' entre les espaces est traité comme un argument.

for %%x in (%*) do (
    echo %%x 
) 

J'ai aussi essayé d'utiliser shift, qui ne semble pas fonctionner soit à droite, l'étouffement des fichiers avec des espaces dans leur nom:

:next 
if not %1 == "" (
    echo %1 

    shift /1 
    goto next 
) 

Quel est le moyen idéal pour parcourir tous les arguments ?

Dans Bash, il suffit d'utiliser "[email protected]" et tout fonctionne simplement ™, mais bien sûr cela ne semble pas être le cas avec les scripts batch Windows.

Répondre

2

Les modificateurs de substitution pour pour les références de variables permettent également d'utiliser les ~ expansions. Voir for command reference.

En utilisant "%%~x" vous devriez obtenir un paramètre correctement cité, similaire à la façon dont bash gère "[email protected]".

@echo off 

setlocal enableextensions 

for %%x in (%*) do (
    echo "%%~x" 
) 

Les caractères, et; peut être utilisé pour séparer les paramètres de commande. Voir command shell overview. Vous devez donc placer des guillemets autour des noms de fichiers contenant ces caractères.

Si vous faites glisser un fichier de l'Explorateur sur le fichier .bat, l'Explorateur ne citera correctement le fichier que s'il contient un caractère espace blanc dans son chemin. Par exemple, D:\a,b,c.exe ne sera pas cité par Explorer et sera donc analysé comme trois arguments séparés par cmd.exe.

Pour faire fonctionner le script avec glisser-déposer depuis l'explorateur de ces cas monstre, vous pouvez utiliser les éléments suivants (laid) travail autour de:

@echo off 

setlocal enableextensions enabledelayedexpansion 

set "args=%*" 
set "args=%args:,=:comma:%" 
set "args=%args:;=:semicolon:%" 

for %%x in (%args%) do (
    set "filepath=%%~x" 
    set "filepath=!filepath::comma:=,!" 
    set "filepath=!filepath::semicolon:=;!" 
    echo "!filepath!" 
) 

Le script introduit une variable d'aide args, où chaque l'occurrence d'un caractère gênant est remplacée par un espace réservé (notez que le caractère deux-points lui-même ne peut pas être utilisé dans un nom de fichier sous Windows).

Le corps de la boucle for utilise une autre variable auxiliaire filepath qui annule la transformation pour produire le chemin d'origine.

+0

Odd; L'Explorateur ne semble pas citer les fichiers avec des virgules dans leur nom, donc le .bat a des problèmes. Ce script fonctionne exactement comme ma solution, sauf que je suppose que c'est un peu plus robuste. – strager

+0

@strager J'ai mis à jour ma solution pour inclure une solution de rechange pour Explorer ne citant pas les noms de fichiers; , correctement. – sakra

+0

Fonctionne bien; Merci! – strager

0

J'ai créé une "fonction" par lots qui effectue une analyse "correcte" des arguments et gère correctement les signes et les points-virgules. Je pense que vous trouverez que cela peut vous aider à résoudre ces problèmes. Tous les détails et un exemple peuvent être trouvés sur mon site: http://skypher.com/index.php/2010/08/17/batch-command-line-arguments/

+0

Je n'arrive pas à accéder à votre lien ... Le serveur est-il en panne? – strager

0

J'ai eu un problème similaire avec les noms de fichiers qui contiennent des signes égal (=), ce qui entraîne la division du nom de fichier en plusieurs arguments. Je l'ai résolu en utilisant "%*".

Si vous avez un fichier avec des espaces, par ex.foo bar baz.txt, ceci sera cité deux fois: ""foo bar baz.txt"". Maintenant, les doubles guillemets doubles sont évités: foo bar baz.txt, ce qui donne %1 = foo, %2 = bar, et %3 = baz.txt. Donc ça ne marche pas.

Si vous avez un fichier avec des espaces ET/OU signe égal, vous pouvez utiliser:

set input=""%*"" 
set input=%input:"=% 
your_program "%input%" 

Maintenant, foo bar=baz.txt sera trois fois cité: """foo bar=baz.txt""". Deux citations seront échappées et input devient "foo bar=baz.txt". Avec la deuxième ligne, les guillemets sont remplacés par rien (enlevé). Vous devez mettre à nouveau les guillemets autour de input lorsque vous l'entrez dans your_program, sinon il verra des espaces comme entrée séparée!

Si vous avez seulement le signe égal, puis ""%*"" fait foo=bar=baz.txt dans ""foo=bar=baz.txt"", qui entre dans votre programme %1 = foo=bar=baz.txt.

Questions connexes