Как удалить |символ из переменной - PullRequest
0 голосов
/ 26 августа 2018

У меня есть код, подобный приведенному ниже:

    FOR /F "tokens=*" %%B IN ('%*') DO (
    ECHO %%B
    SET data=%%B
    ECHO %data%
    )        

%% B содержит один или несколько символов |символ, например значение %% B равно Первый |Второй |В-третьих .Функция SET data = %% B или SET data = "%% B" не работает.Когда% data% вызывается обратно, это показывает, что Echo выключено.

Мне нужно удалить |символ из %% B и сохраните его в переменной% data%.Но я не знаю, как?

Буду благодарен, если кто-нибудь предоставит какое-либо решение ...

1 Ответ

0 голосов
/ 26 августа 2018

Первое решение использует:

@echo off
setlocal EnableExtensions EnableDelayedExpansion

for /F delims^=^ eol^= %%B in ('%*') do (
    set "data=%%B"
    set "data=!data:|=!"
    echo(!data!
)

endlocal

tokens=* приводит к присвоению переменной цикла B всей строки с удаленными начальными пробелами / табуляциями, в то время как delims= приводит к присвоению переменнойпеременная цикла B вся строка, включая начальные пробелы / табуляции.Поэтому определение пустого списка разделителей в целом лучше.

FOR по умолчанию игнорирует пустые строки, а строки, начинающиеся с точки с запятой, поскольку ; по умолчанию интерпретируются как конецсимвол строкиПо этой причине необычная строка опции, не заключенная в двойные кавычки delims^=^ eol^=, используется здесь для определения пустого списка разделителей и без символа конца строки.Символ каретки ^ используется для экранирования следующего символа, чтобы он интерпретировался как буквальный символ, а не как разделитель аргументов, хотя и не заключен в строку аргумента с двойными кавычками.

Но есть одна проблема с этим решением:Строка, содержащая один или несколько восклицательных знаков !, не обрабатывается корректно, поскольку командный процессор Windows интерпретирует в командной строке set "data=%%B" каждый ! как начало / конец отложенной ссылки на переменную среды и заменяет строку между двумя восклицательными знаками натекущее значение переменной окружения с этим именем или без нее в переменной, не существующей с таким именем, и удаляет все после !, если больше нет !.

Существует как минимум три решения.

Первый включает и отключает отложенное расширение в цикле.

@echo off
setlocal EnableExtensions DisableDelayedExpansion

for /F delims^=^ eol^= %%B in ('%*') do (
    set "data=%%B"
    setlocal EnableDelayedExpansion
    set "data=!data:|=!"
    echo(!data!
    endlocal
)

endlocal

Пожалуйста, прочитайте этот ответ для получения подробной информации о командах SETLOCAL и ENDLOCAL , поскольку они делают гораздо больше, чем простовключение / выключение отложенного расширения в цикле.

( между echo и значением переменной среды data используется в случае, если строка содержит только | без или с дополнительными пробелами /табуляция data становится либо неопределенной, либо строкой, состоящей только из пробелов / табуляций.Пробел между echo и !data! будет при исполнении только команды echo с пропущенным пробелом и 0 или более пробелов / табуляций, что приведет к получению вывода ECHO is off. вместо пустой строки или строки с только пробелами /вкладки.Открывающая круглая скобка предотвращает это и интерпретируется cmd.exe как разделитель между командой echo и строкой ее аргумента, которая в этом случае всегда начинается с (. ECHO игнорирует первый символ строки аргумента на выходе, если строка аргумента не /? и, следовательно, ( никогда не выводится.

Второе решение использует подпрограмму:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

for /F delims^=^ eol^= %%B in ('%*') do (
    set "data=%%B"
    call :ProcessLine
)

endlocal
goto :EOF

:ProcessLine
set "data=%data:|=%"
echo(%data%
goto :EOF

Примечание: echo %data% может привести к неожиданному поведению, если строка содержит символы, такие как операторы перенаправления < и > или оператор & для WindowsКомандный процессор выполняет echo(%data% после замены %data% текущей строкой переменной среды data.Даже set "data=%data:|=%" может быть проблематичным в зависимости от строки, содержащей " и <>&.Таким образом, это решение на самом деле небезопасно.

См. Также Куда возвращается GOTO: EOF?

Третье решение использует ссылку на переменную среды с двойным процентом ииспользование команды CALL для принудительного двойного анализа командной строки, содержащей %%variable%% вместо обычного %variable%.

@echo off
setlocal EnableExtensions DisableDelayedExpansion

for /F delims^=^ eol^= %%B in ('%*') do (
    set "data=%%B"
    call set "data=%%data:|=%%"
    call echo(%%data%%
)

endlocal

Примечание Также это решениене совсем безопасно в зависимости от данных, как второе решение.

См. также Как интерпретатор сценариев команд Windows (CMD.EXE) анализирует?

Командный процессор Windowsпредназначен для выполнения команд и приложений, а не для переформатирования или обработки CSV файлов с использованием вертикальной черты в качестве разделителя / разделителя.

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

  • call /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • set /?
  • setlocal /?

И читать также ответ на Почему не выводится строка с «echo% var%» после использования «set var = text» в командной строке? по причине использования синтаксиса set "variable=value" вместо set variable=value или set variable="value".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...