IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Scripts/Batch Discussion :

Caractères spéciaux dans les variables [Batch]


Sujet :

Scripts/Batch

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 67
    Points
    67
    Par défaut Caractères spéciaux dans les variables
    Salut,

    comment échapper les caractères spéciaux tels que "!", "%" ou "&" compris dans une variable "%%a" (issue d'une boucle qui explore un répertoire avec la commande dir) ?

    Car cette variable "%%a" est malheureusement inutilisable par la suite, si elle comprend ces caractères spéciaux.

    J'ai essayé la commande sed mais je n'arrive pas à la faire marcher, d'autant plus que de toutes manières le simple fait de devoir utiliser un fichier texte pour la manoeuvre signifie de devoir "echo %%a>fichier.txt" ce qui implique qu'on perd les "!" contenue dans la variable !

    C'est un vrai casse-tête...

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 67
    Points
    67
    Par défaut
    Aïe Aïe Aïe, je m'en sort pas.

    Toutes les solutions que j'envisage passent par :
    - la construction d'une variable
    - et l'écriture de cette variable dans un fichier, ce qui du coup supprime les caractères spéciaux et rebelotte...

    Donc on ne peut jamais avoir une variable propre.

    Ni même simplement faire une simple recherche avec Find (en vue de zapper des chemins avec des "!" par exemple), parce que là encore il faut chercher dans un fichier, donc écrire la variable dedans !


    D'Ooh !

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 165
    Points : 90
    Points
    90
    Par défaut
    Salut,

    tu peux donner quelques exemples ? avec le résultat attendu

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 67
    Points
    67
    Par défaut
    edit : en amont du batch il y a un "setlocal enabledelayedexpansion"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    set rep=C:\Documents and Settings\*****\Bureau
    ::for /f "delims=" %%a in ('dir /b /s /a:-d "%rep%"') do (
    for /f "delims=" %%a in ("Salut!") do (
    	call :search "%%a"
    	if "!spec!"=="yes" echo caractere trouve dans %%a
    )
    pause
    goto :eof
    
    		:search
    		set match=%~1
    		echo %match% |findstr "^!">nul
    		if errorlevel=1 set spec=no&& goto :eof
    		if errorlevel=0 set spec=yes&& goto :eof
    		goto :eof
    Le "for" que j'ai désactivé avec "::" explore mon bureau sur lequel se trouve un lien "JOUER !", donc un fichier qui a comme chemin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    C:\Documents and Settings\*****\Bureau\JOUER !.lnk
    Comme la commande "search" ne me renvoyait pas au final "caractere trouve dans %%a" j'ai essayé avec une simple string "Salut!", mais ça ne renvoit toujours pas.

    Du coup je crois que le MS DOS c'est vraiment limité : dès qu'il y a des "!" dans le nom des fichier, c'est foutu.

    Et c'est embêtant vu que je suis en train de construire un batch qui sauvegarde les données contenues dans "AllUsers" et dans les profils d'utilisateurs avant un formatage (genre Application Data etc), et que dans ces répertoires se trouvent parfois des fichiers avec des "!" ou des "%" ou encore des "$".
    Un simple raccourcis HTML dans "Favoris" contient parfois des caractères à la noix...

    Les problèmes qui s'ensuivent sont divers, ça va de la variable qui ne peu plus servir à un "if exist" ou un "set size=%~z1", à des messages d'erreurs en tous genre comme "la commande "machintruc" n'existe pas (genre la fin du chemin après un "&" est comprise comme étant une commande -_-).

    Moi j'veux bien que quelques fichiers soit zappés, mais ce qui m'ennuit vraiment c'est les messages d'erreurs qui plombent la fenêtre de commande. C'est inesthétique, surtout quand on se plie en 4 pour faire un truc propre et lisible.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 67
    Points
    67
    Par défaut
    Par contre si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo !match! |findstr /c:"JOUER .lnk">nul
    il va trouver ! Donc ça prouve bien que "%%a" remplace les caractères spéciaux par des espaces !

    Du coup après si on fait un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if not exist "%%a" echo n'existe pas
    Ca affiche que le chemin n'existe pas.

    J'suis démoli. Deux semaines de labeur pour me ramasser sur un truc pareil.

    Si ça continue j'abandonne l'informatique. C'est trop de prise de tête pour inventer des trucs que les gens compétents n'ont pas daigné inventer, et tout ça pour au final s'apercevoir que nos efforts n'aboutissent pas, encore une fois à cause d'un truc qui a pas été fait correctement...

    Si vous connaissez un soft qui permette de sauvegarder tout ce qu'il y a à sauvegarder avant un formatage (Application Data, Favoris, Mes Documents, etc), j'suis preneur.

  6. #6
    Membre éprouvé
    Avatar de maxim_um
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    895
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 895
    Points : 1 018
    Points
    1 018
    Par défaut
    Salut,

    Citation Envoyé par DeVit Voir le message
    J'suis démoli. Deux semaines de labeur pour me ramasser sur un truc pareil.
    Si je ne m'abuse, il a déjà été question de caractères réservés dans certaines de tes discussions. Non?

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 67
    Points
    67
    Par défaut
    Oui mais quoi qu'il en soit je n'arrive pas à voir le rapport avec le problème actuel, même en relisant mes précédent topics. :/

  8. #8
    Membre éprouvé
    Avatar de maxim_um
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    895
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 895
    Points : 1 018
    Points
    1 018
    Par défaut
    Ben disant que si tu utilises dans les noms de tes fichiers des caractères réservés par l'interpréteur de commande, là forcément, leurs traitements par le biais de ce dernier n'en seront que plus compliqués. Mais ça ne veut pas dire que c'est insurmontable. Comme le sujet a été traité à de nombreuses reprises, il faudrait que tu fasses une recherche sur le forum. Il y a beaucoup d'exemples de script permettant de contourner ce problème.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 67
    Points
    67
    Par défaut
    Bon j'ai rien trouvé. J'ai tapé "caractères spéciaux" dans la recherche avancée, catégorie "Programmation Windows - Scripts/Batch".

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 67
    Points
    67
    Par défaut
    J'ai trouvé moyen de ruser !

    1 - On balance le contenu de la commande 'dir' dans un fichier.
    2 - Ô magie ! les fameux caractères sont copié dedans !
    3 - Par contre on est toujours dans le caca pour récupérer les lignes du fichier, puisque le passage dans une variable va virer les caractères spéciaux.
    4 - Il faut donc trouver le moyen de rajouter des "^" devant chaque caractère spécial, dans le fichier.
    5 - Et pas possible d'utiliser Switch, Sed ou autre commande sensée remplacer des caractères par d'autres. Ca ne marche pas, impossible, essayez, vous verrez ! La gestion des "^" comme échappement est désatreuse...
    6 - Donc pas d'autres solution que de demander à l'utilisateur de rajouter lui-même les "^", manuellement !

    Je repasse dès que possible donner plus de détails sur la façon dont procéder, parce qu'il faut épurer le fichier pour ne laisser que les chemins avec caractères spéciaux.

  11. #11
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    Citation Envoyé par DeVit Voir le message
    J'ai trouvé moyen de ruser !

    1 - On balance le contenu de la commande 'dir' dans un fichier.
    2 - Ô magie ! les fameux caractères sont copié dedans !
    3 - Par contre on est toujours dans le caca pour récupérer les lignes du fichier, puisque le passage dans une variable va virer les caractères spéciaux.
    4 - Il faut donc trouver le moyen de rajouter des "^" devant chaque caractère spécial, dans le fichier.
    5 - Et pas possible d'utiliser Switch, Sed ou autre commande sensée remplacer des caractères par d'autres. Ca ne marche pas, impossible, essayez, vous verrez ! La gestion des "^" comme échappement est désatreuse...
    6 - Donc pas d'autres solution que de demander à l'utilisateur de rajouter lui-même les "^", manuellement !

    Je repasse dès que possible donner plus de détails sur la façon dont procéder, parce qu'il faut épurer le fichier pour ne laisser que les chemins avec caractères spéciaux.
    peux-tu donner un exemple de ce que tu veux faire et dans quel optique

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 67
    Points
    67
    Par défaut
    PREAMBULE
    #alluserspaths est un fichier contenant des chemins de dossiers à sauvegarder dans "AllUsers".
    !AllUsers! a comme valeur "%systemdrive%\Documents and Settings\All Users"
    #missing est un fichier dans lequel on liste les répertoires manquant
    #temp1 et #temp2 sont des fichiers temporaires
    #problems est un fichier dans lequel on copie tous les chemins en vrac, et ensuite on enlève ce qui est valide.
    #list est un fichier dans lequel on liste les fichier valides.

    EXTRAIT DE CODE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    setlocal enabledelayedexpansion
    :: On y va : on commence par "AllUsers"
    for /f "usebackq delims=" %%a in ("%#alluserspaths%") do (
    	set rep=!AllUsers!\%%a
    	if not exist "!rep!" echo !rep!>>"%#missing%"
    	if exist "!rep!" (
    		call :2_Spechar "!rep!"
    		if "!spechar!"=="no" call :2_Excluded "!rep!"
    		if "!excluded!"=="no" call :2_Explore "!rep!"
    	)
    )
    
    echo ON SE PREPARE A SUPPRIMER LES LIGNES VIDE DANS "PROBLEMS.TXT"
    pause
    call %_commands%\sed\sed.exe "/^$/d" "%#problems%"
    echo %totalfiles%>"%#temp1%"
    echo %totalsize%>"%#temp2%"
    endlocal
    pause
    exit
    
    ::FIN
    ::------------------------------------------------------------
    
    ::  On explore à fond les répertoires, on vérifie s'ils ont à être exclus, et si non, on 
    	::  calcule leur taille, et on fait tourner un compteur pour avoir leur nombre/taille total.
    
    	:2_Explore
    	set rep=%~1
    	:: Une petite précaution pour éviter les répertoires ne contenant aucun fichier :
    	for /f "tokens=1 delims= " %%a in ('dir /s "%rep%" ^| findstr "fichier(s)"') do (
    		set match=%%a
    	)
    	:: Maintenant le code ci-dessous ne devrait plus afficher "Fichier Introuvable".
    	if !match! gtr 0 (
    		dir /b /s /a:-d "%rep%">>"%#problems%"
    		for /f "usebackq delims=" %%a in ("%#problems%") do (
    			if "%%a" neq "" (
    				call :2_Spechar "%%a"
    				if "%spechar%"=="no" call :2_Excluded "%%a"
    				if "!excluded!"=="no" echo %%a>>"%#list%" & call :2_Calcul "%%a"
    			)
    		)
    	) 
    	goto :eof
    	
    	:2_Spechar
    	:: ATTENTION : ne pas mettre de parenthèses aux conditions ci-dessous !
    	:: Car précisément "%~1" peut contenir des caractères spéciaux tels que
    	:: des parenthèses, et interférer avec le code !
    	set target=%~1
    	if exist "%target%" call %_commands%\switch\switch.exe "%#problems%" "%target%" ""
    	if exist "%target%" set spechar=no
    	if not exist "%target%" set spechar=yes
    	goto :eof
    
    	
    	:2_Excluded
    	echo %~1>"%#temp1%"
    	for /f "usebackq delims=" %%e in ("%#exclude%") do (
    		set match=%%e
    		find "!match!" "%#temp1%">nul
    		if errorlevel=2 call %_messages%\error "119" "BACKUP.cmd" & goto :eof
    		if errorlevel=1 set excluded=no& goto :eof
    		if errorlevel=0 set excluded=yes& goto :eof
    	)
    	goto :eof
    
    	:2_Calcul
    	::  Calcul du nombre de fichiers, et de la taille totale.
    	set /a totalfiles+=1
    	set size=%~z1
    	set /a totalsize+=%size%
    	goto :eof
    Donc pour résumer :
    1 - on lit "AllUsersPath.dat", on a une première itération, par exemple "Application Data". On compose le chemin, on appelle "Spechar" pour voir si y'a pas de saloperie dans le nom.
    2 - Ensuite on regarde si ce chemin n'est pas dans la liste des chemins à exclure (que l'utilisateur a pu modifier).
    3 - Quand tout est ok, on explore en appelant "2_Explore".
    4 - Après une simple précaution, on copie le résultat de la commande 'dir' dans un fichier. En gros on copie tous les chemins des fichiers du répertoire dans le fichier "problems.txt".
    5 - On analyse ce fichier ligne par ligne pour voir si les chemins "existent" : ça permet de savoir s'ils contiennent des caractères spéciaux, car dans un tel cas il "n'existeront pas".
    6 - Si c'est clean on vérifie qu'ils ne font pas partie de la liste des exclus, et on les vire de "problems.txt" avec la commande Switch. Sinon, on les laisse dedans et on ne fait rien d'autre.

    L'objectif ici est :
    - d'explorer les répertoires indiquées pour calculer le nombre et la taille totale des fichiers, en prenant en compte une liste d'exclusion.
    - et au passage isoler dans "problems.txt" les chemins invalides, que l'on aura pu correctement "copier tels quels dans le fichier" grâce à l'astuce de la commande dir
    - bien entendu il ne faut plus du tout bouger ces lignes (contenant des caractères spéciaux) du fichier problems.txt, sous peine de perdre les caractères spéciaux via un passage dans une variable !

    Donc à la fin on se retrouve avec un fichier "problems.txt" qui a plein de lignes vide (tout ce qu'on a supprimé qui était valide), et j'aimerais donc virer ce lignes vides, pour que l'utilisateur qui devra intervenir manuellement sur ce fichier n'est pas à scroller comme un malade pour trouver les lignes contenant les chemins à problème.

    Or Sed ne fonctionne absolument pas -_- (voir ce topic)

  13. #13
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    Citation Envoyé par DeVit Voir le message

    Or Sed ne fonctionne absolument pas -_- (voir ce topic)
    alors utilise FINDSTR

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 67
    Points
    67
    Par défaut
    Si je ne me trompe, tu m'as conseillé ça :
    findstr /vir "^$" espace.txt > sans_espace.txt
    Ce qui consiste à "ne prendre que les lignes qui ne sont pas vide" pour aller les copier dans un autre fichier.

    Mais on perd les caractères spéciaux au passage, donc ça ne va pas :/

  15. #15
    Futur Membre du Club
    Inscrit en
    Décembre 2013
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 5
    Points : 6
    Points
    6
    Par défaut
    J'ai moi aussi souvent buté sur ce problème : Comment faire pour qu'une variable, qui prend successivement comme valeur des noms de fichiers, puisse ne pas faire planter le script au moment où elle tombe sur un nom de fichier composé d'un caractère &.

    Et enfin en faisant des tests, je suis tombé sur une solution, qui ne fonctionne cependant que si on peut se permettre que contenu de la variable ait le caractère '&' remplacé par un autre.


    1er cas, le plus simple:
    %var% contient abc&def

    set var=%var:&=_%

    %var% contient maintenant abc_def


    2ème cas, le plus courant:
    La variable est %%i puisqu'on est à l'intérieur d'une boucle for, la syntaxe va changer:

    à cet instant %%i contient abc&def

    set var=%%i
    set "var=!var:&=_!"

    !var! contient maintenant abc_def

    Bien sûr les expansions retardées sont activées.
    La position des guillemets semble obligatoire

  16. #16
    Nouveau Candidat au Club
    Homme Profil pro
    Sans emploi
    Inscrit en
    Juillet 2014
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Sans emploi
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juillet 2014
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Solution
    Je voulais remplacer & par ^& dans la variable "Titre" saisie par invite de commandes puis la commande set Titre=%Titre:&=^^^&% a fait mon bonheur =)

    ^^^& : On échappe les caractères ^ et & séparément, je suppose =)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Batch] Utiliser des caractères spéciaux dans les noms de variables?
    Par DeVit dans le forum Scripts/Batch
    Réponses: 6
    Dernier message: 09/10/2009, 11h33
  2. Caractère spéciaux dans les requêtes SQL
    Par Thundara dans le forum SGBD
    Réponses: 3
    Dernier message: 17/04/2008, 11h15
  3. Caractères spéciaux dans les noms de variables POST
    Par guidav dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 03/09/2007, 13h36
  4. [SQL] Problème d'affichage de caractère spéciaux dans une variable chaîne
    Par Kryptonaute dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 18/08/2006, 08h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo