J'essaie de convertir toutes les barres obliques inverses () en barres obliques (/) dans une variable qui contient un nom de fichier et un emplacement. J'ai lu à ce sujet et vu:
%variable:str1=str2%
et
set "var=%var:\=/%"
que j'ai essayé, mais je ne suis évidemment pas en train de faire les choses correctement.
Voici la section pertinente de mon script .bat:
FOR %%f IN ("E:\myfiles\app1\data\*.csv") DO (
echo %%f
set "f=%%f:\=/%"
echo %%f
echo.
)
La sortie affiche chaque nom de fichier répertorié deux fois.
c'est-à-dire cette ligne:
set "f=f:\=/%"
ne fait pas ce que je veux. Quelqu'un peut-il voir ce que je fais mal?
Dans une instruction de bloc (a parenthesised series of statements)
, Le bloc entier est analysé et alors exécuté. Tout %var%
Dans le bloc sera remplacé par la valeur de cette variable au moment où le bloc est analysé - avant l'exécution du bloc - la même chose s'applique à une FOR ... DO (block)
.
Par conséquent, IF (something) else (somethingelse)
sera exécutée en utilisant les valeurs de %variables%
Au moment où le IF
sera rencontré.
Deux façons courantes de résoudre ce problème sont 1) d'utiliser setlocal enabledelayedexpansion
Et d'utiliser !var!
À la place de %var%
Pour accéder à la valeur modifiée de var
ou 2) pour appeler un sous-programme pour effectuer un traitement supplémentaire en utilisant les valeurs modifiées.
Notez donc l'utilisation de CALL ECHO %%var%%
Qui affiche la valeur modifiée de var
.
Votre code contient deux variables distinctes appelées f
.
Le premier est le métavariable de contrôle de boucle appelé f
et référencé par %%f
.
La seconde est la variable d'environnement commune f
qui est établie par l'instruction set "f=..."
. Cette variable est accessible en utilisant %f%
mais dans un block
, elle semblera conserver la valeur qu'elle avait lorsque le for
de contrôle a été analysé (en fait, tout %var%
est remplacé au moment de l'analyse par la valeur de var
à ce moment-là)
metavariables
ne peut pas être utilisé dans des instructions de manipulation de chaînes comme des sous-chaînes ou des substituts, seules les variables d'environnement courantes peuvent être utilisées pour ces opérations, vous devez donc affecter la valeur de la métavariable f
à la variable d'environnement f
et puis exécutez la tâche de substitution de chaîne de la variable d'environnement f
.
La torsion, bien sûr, est que vous devez utiliser delayedexpansion
et la syntaxe !var!
Pour accéder à la valeur modifiée d'une variable d'environnement dans un bloc.
Donc,
setlocal enabledelayedexpansion
for...%%f...do (
echo %%f
set "f=%%f"
set "f=!f:\=/!"
echo !f!
)
echo just for demonstration %f% !f! %%f
Cela définit la valeur de f
de la manière requise (bien sûr, vous pouvez toujours changer le nom pour éviter toute confusion ...)
La dernière ligne est simplement pour montrer que la valeur finale acquise par f
est accessible en dehors de la boucle en tant que %f%
Ou !f!
, Et que %%f
est hors contexte et affiché comme %f
.
Une autre façon de procéder sans delayedexpansion
est
for...%%f...do (
echo %%f
set "f=%%f"
call set "f=%%f:\=/%%"
call echo %%f%%
)
echo just for demonstration %f% !f! %%f
la différence étant l'utilisation de call
et le doublement du %
s, et la dernière ligne affichera !f!
comme cela - un littéral, car en dehors de delayedexpansion
mode, !
n'est qu'un autre caractère sans signification particulière pour cmd
.
Cela changera les barres obliques inverses en barres obliques dans une variable:
set "variable=E:\myfiles\app1\data\*.csv"
set "variable=%variable:\=/%"
echo "%variable%"
Cela semble fonctionner pour moi:
echo off
setlocal enabledelayedexpansion
FOR %%f IN ("C:\tools\workspace\*") DO (
set old=%%f
echo !old!
set new=!old:\=/!
echo !new!
echo.
)
L'utilisation d'une variable distincte plutôt que de la variable de boucle fait la différence, tout en permettant une expansion retardée car la variable sous-station syntex utilisant la variable de boucle %% f ne semble pas fonctionner.
Cela fonctionnera pour changer le backslashe pour transférer les barres obliques dans les fenêtres:
typedef std::basic_string<TCHAR> tstring;
tstring pathbasic = tstring(programdata) + _T("\\myfile.txt");
std::replace(pathbasic.begin(), pathbasic.end(), _T('\\'), _T('/'));