Подтвердить что ты не робот

Изменение обратной косой черты для косой черты в оконном пакетном файле

Я пытаюсь преобразовать все обратные слэши() в пересылку косых черт (/) в переменной, которая содержит имя и местоположение файла. Я читал об этом и видел:

%variable:str1=str2%

и

set "var=%var:\=/%"

который я попытался, но я, очевидно, не понимаю.

Вот соответствующий раздел моего .bat script:

FOR %%f IN ("E:\myfiles\app1\data\*.csv") DO (
  echo %%f  
  set "f=%%f:\=/%"
  echo %%f  
  echo.                 
)

Вывод показывает каждое имя файла, указанное дважды.

то есть. эта строка:

set "f=f:\=/%"

не делает то, что я хочу. Может ли кто-нибудь увидеть, что я делаю неправильно?

4b9b3361

Ответ 1

В блочном выражении (a parenthesised series of statements) выполняется синтаксический анализ целого и , затем. Любой %var% внутри блока будет заменен значением переменной в момент анализа блока - до того, как будет выполнен блок - то же самое относится к FOR ... DO (block).

Следовательно, IF (something) else (somethingelse) будет выполняться с использованием значений %variables% во время возникновения IF.

Два общих способа преодоления этого: 1) использовать setlocal enabledelayedexpansion и использовать !var! вместо %var% для доступа к измененному значению var или 2) для вызова подпрограммы для дальнейшей обработки с использованием измененные значения.

Обратите внимание, что использование CALL ECHO %%var%%, которое отображает измененное значение var.

Ваш код содержит две отдельные переменные, называемые f.

Первый - это метастабильный цикл, называемый f и ссылающийся на %%f.

Вторая - это общая переменная среды f, которая устанавливается оператором set "f=...". Доступ к этой переменной можно получить с помощью %f% , но в block, он сохранит значение, которое было у него при анализе контрольного for (фактически, любой %var% заменен во время разбора на значение var в это время)

metavariables не может использоваться в операторах строковой манипуляции, таких как подстроки или заменители, для этих операций могут использоваться только общие переменные среды, поэтому вам необходимо присвоить значение метаобменимой f переменной окружения f а затем выполнить задачу замены строки переменной окружения f.

Конечно, вы должны использовать синтаксис delayedexpansion и !var! для доступа к модифицированному значению переменной среды внутри блока.

Итак,

setlocal enabledelayedexpansion
for...%%f...do (
  echo %%f
  set "f=%%f"
  set "f=!f:\=/!"
  echo !f!
)
echo just for demonstration %f% !f! %%f

Это устанавливает значение f необходимым образом (конечно, вы всегда можете изменить имя, чтобы избежать путаницы...)

Последняя строка - это просто показать, что конечное значение, полученное с помощью f, можно получить за пределами цикла как либо %f%, либо !f!, а %%f - вне контекста и показано как %f.

Другой способ сделать это без delayedexpansion -

for...%%f...do (
  echo %%f
  set "f=%%f"
  call set "f=%%f:\=/%%"
  call echo %%f%%
)
echo just for demonstration %f% !f! %%f

разница заключается в использовании call и удвоении % s, а в финальной строке будет отображаться !f! как раз это - литерал, поскольку вне режима delayedexpansion ! - это просто другое символ, не имеющий особого значения для cmd.

Ответ 2

Это изменит обратную косую черту на перекосы в переменной:

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

Ответ 3

Кажется, это работает для меня:

echo off

setlocal enabledelayedexpansion

FOR %%f IN ("C:\tools\workspace\*") DO (
  set old=%%f
  echo !old!
  set new=!old:\=/!
  echo !new!  
  echo.                 
)

Использование отдельной переменной, а не переменной цикла, делает разницу, а также позволяет замедленное расширение, поскольку синтаксис переменной подстановки с использованием переменной цикла %% f dosn't, похоже, работает.

Ответ 4

Это будет работать для изменения обратной косой черты на прямую косую черту в окнах:

 typedef std::basic_string<TCHAR> tstring;
 tstring pathbasic = tstring(programdata) + _T("\\myfile.txt");
 std::replace(pathbasic.begin(), pathbasic.end(), _T('\\'), _T('/'));