2013-03-11 7 views
3

Я пытаюсь заменить ~ на %HOME% в пакетном скрипте. Это то, что я до сих пор:cmd строка замена специального символа

@echo off 
setlocal enabledelayedexpansion 
set str=%* 
set replacement=%HOME% 
set str=%str:~=!replacement!% 
echo %str% 

Это не работает, как я ожидаю, вероятно, потому, что мне нужно, чтобы избежать тильды ~ в некотором роде.

Когда я убегаю с ^, str не изменился. Без выхода str - это строка str:~=<my_home_path>.

Как я могу изменить "~/work/my_folder" на "C:/Users/login/work/my_folder"?

+0

Зная партию, длина кода, используемого для решения этой проблемы не стоит. Можно ли изменить знак на что-то еще? –

+0

Знаете ли вы решение, даже длинное? Мне нужно это, чтобы вызвать пакетные скрипты из инструментов GNU, которые настаивают на использовании '~' в путях (даже если я его прописал). – Gauthier

+0

Нет, и я нахожусь на моем телефоне в данный момент, но я уверен, что когда дбэнем просыпается, он ответит. –

ответ

3

Если ~ всегда первый символ, вы можете использовать несколько, как это:

@echo off &setlocal enabledelayedexpansion 
set "str=|~/work/my_folder" 
set "replacement=C:/Users/login" 
set str=%str:|~=!replacement!% 
echo %str% 
+0

Это сработало! Требование '' 'быть первым приемлемо, и я могу даже заменить' '' на все, что мне нравится, например. 'Dummy_string_asdf'. Мне очень странно, что для этого нет «чистого пути», но, добавив что-то перед '~' ... – Gauthier

+0

О, подождите, это не так. Мне нужно иметь возможность заменить '~' в середине строки, которая содержит кучу аргументов команды. – Gauthier

+0

Но между '~' всегда существует пробел, поэтому я могу использовать это как строку для поиска: 'set str =% str: ~ =! Replacement!%' (То есть ' ~' вместо '~') – Gauthier

3

Или немного сложнее:

@echo off &setlocal enabledelayedexpansion 
set "str=~/work/my_folder -param one ~ two:~" 
set "replacement=C:/Users/login" 
call :strlen str len 
set /a len-=1 
for /l %%i in (0,1,%len%) do if "!str:~%%i,1!"=="~" (set "new=!new!%replacement%") else set "new=!new!!str:~%%i,1!" 
echo %new% 
goto :eof 

:strlen 
:: list string length up to 8189 (and reports 8189 for any string longer than 8189) 
:: function from http://ss64.org/viewtopic.php?pid=6478#p6478 
( setlocal enabledelayedexpansion & set /a "}=0" 
    if "%~1" neq "" if defined %~1 (
     for %%# in (4096 2048 1024 512 256 128 64 32 16) do (
      if "!%~1:~%%#,1!" neq "" set "%~1=!%~1:~%%#!" & set /a "}+=%%#" 
     ) 
     set "%~1=!%~1!0FEDCBA9876543211" & set /a "}+=0x!%~1:~32,1!!%~1:~16,1!" 
    ) 
) 
endlocal & set /a "%~2=%}%" & exit /b 
endlocal 

Выход:

C:/Users/login/work/my_folder -param one C:/Users/login two:C:/Users/login

Это не работает с восклицательными знаками.

0

Я думаю, вы уже довольно близко, за исключением нескольких незначительных проблем.

Во-первых, в Windows нет переменной окружения для %home% - по крайней мере, не для моей системы. Я думаю, что переменная, которую вы ищете, - %userprofile%. У ss64.com есть отличный список и описание Windows environment variables.

Другая проблема заключается в том, что вы задерживаете расширение в неправильном порядке. Попробуйте изменить предпоследнюю строку на set str=!str:~=%userprofile%!, чтобы внутренняя переменная расширялась перед внешним. Не может быть и плохой перевод переводов косых черт назад.

@echo off 
setlocal enabledelayedexpansion 
set str=%* 
set "str=!str: ~= %userprofile%!" 
set "str=!str:*~=%userprofile%!" 
set "str=%str:\=/%" 
echo %str% 

Пример вывода:

C:\Users\me\Desktop>test ~/.bash_profile 
C:/Users/me/.bash_profile 

C:\Users\me\Desktop>test arg1 arg2 ~/.bash_profile 
arg1 arg2 C:/Users/me/.bash_profile 
+0

это не работает (на XP). – Endoro

+0

Вы правы, я создал свою собственную переменную окружения% HOME%, она удобна (для меня), когда я использую Bash. Вы также правы относительно косых черт, хотя это не имеет значения для рассматриваемого приложения (ack). Более того, я хочу, чтобы косые черты (чтобы emacs делали ссылки пути к файлам). Вы протестировали свой сценарий и видели, как он работает? Это не здесь, результатом 'ack asdf ~ qwer' является:' str: ~ = C: \ Users \ login'. – Gauthier

+0

Проверьте это? Зачем мне это проверять? Тьфу! Да, я вижу, что я сделал неправильно. Тильда имеет особое значение в переменной подстановке. Добавьте перед ним звездочку, и она исправляет ее. – rojo

0
@ECHO OFF 
    CLS 
    SET OldStr=~\work\my_folder 
    SET NewStr= 
    SET Replacement=C:\Users\login\work\my_folder 
    CALL :ReplaceHome "%OldStr%" 
    ECHO %NewStr% 
    EXIT /b %ERRORLEVEL% 

    :ReplaceHome 
    IF "%~1"=="" EXIT /B %ERRORLEVEL% 
    SET TempStr=%~1 
    IF "%TempStr:~0,1%"=="~" SET TempStr=%Replacement%%TempStr:~1% 
    SET NewStr=%NewStr%%TempStr:~0,1% 
    CALL :ReplaceHome "%TempStr:~1%" 
    EXIT /B %ERRORLEVEL% 
Смежные вопросы