web-dev-qa-db-fra.com

Changer la barre oblique inverse en barre oblique dans le fichier de commandes Windows

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?

25
user3253319

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.

20
Magoo

Cela changera les barres obliques inverses en barres obliques dans une variable:

set "variable=E:\myfiles\app1\data\*.csv"
set "variable=%variable:\=/%"
echo "%variable%"
62
foxidrive

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.

4
dethorpe

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('/'));
0
Lakshya Bhardwaj