Как вы вырезаете кавычки из строки ECHO в пакетном файле Windows?
У меня есть пакетный файл Windows, который я создаю, но у меня есть ECHO большая сложная строка, поэтому мне нужно поставить двойные кавычки с обоих концов. Проблема в том, что кавычки также являются ECHOed для файла, который я пишу. Как вы ECHO такую строку и отключите кавычки?
UPDATE:
Я провел последние два дня, работая над этим, и, наконец, смог соединить что-то вместе. Ответ Ричарда работал, чтобы стричь кавычки, но даже когда я помещал ECHO в подпрограмму и напрямую выводил строку, Windows все еще зависала на символах в строке. Я соглашусь на ответ Ричарда, так как он отвечает на заданный вопрос.
Я закончил использование решения Greg sed, но мне пришлось его модифицировать из-за ошибок/особенностей sed/windows (это не помогло, чтобы в нем не было документации). Есть несколько предостережений для использования sed в Windows: вам нужно использовать двойные кавычки вместо одиночных кавычек, вы не можете избежать двойных кавычек в строке напрямую, вы должны положить конец строке, убежать с помощью ^ (so ^ ) then beqin quote для следующего раздела. Кроме того, кто-то указал, что если вы подключаете вход к sed, есть ошибка с трубкой, находящейся в строке (я не смог проверить это, так как в моем конечном решении я только что нашел способ не иметь всех кавычек в середине строки и просто удалить все кавычки, Я никогда не смог бы удалить конечный результат сам.) Спасибо за помощь.
Ответы
Ответ 1
Команда вызова имеет встроенную функциональность. Чтобы процитировать помощь для вызова:
Substitution of batch parameters (%n) has been enhanced. You can
now use the following optional syntax:
%~1 - expands %1 removing any surrounding quotes (")
Вот пример:
@echo off
setlocal
set mystring="this is some quoted text"
echo mystring=%mystring%
call :dequote %mystring%
echo ret=%ret%
endlocal
goto :eof
:dequote
setlocal
rem The tilde in the next line is the really important bit.
set thestring=%~1
endlocal&set ret=%thestring%
goto :eof
Вывод:
C:\>dequote
mystring="this is some quoted text"
ret=this is some quoted text
Я должен счесть метод "туннелирования переменных среды" (endlocal & set ret =% thestring%) Тиму Хилу, 'Windows NT Shell Scripting'. Это единственная книга, которую я когда-либо видел, которая обрабатывает пакетные файлы с любой глубиной.
Ответ 2
Вы можете использовать конструкцию %var:x=y%
, которая заменяет все x
на y
.
См. этот пример, что он может сделать:
set I="Text in quotes"
rem next line replaces " with blanks
set J=%I:"=%
echo original %I%
rem next line replaces the string 'in' with the string 'without'
echo stripped %J:in=without%
Ответ 3
Для печати строки без кавычек можно использовать следующий подход:
echo|set /p="<h1>Hello</h1>"
Ответ 4
Чтобы удалить все кавычки из заданной переменной, вам потребуется Delayed Variable Expansion для безопасного расширения переменной и ее обработки. Расширение с использованием знаков процента (т.е. %VAR%
и %1
) по своей сути небезопасно (они уязвимы для ввода команд; читайте это для деталей).
SETLOCAL EnableDelayedExpansion
SET VAR=A ^"quoted^" text.
REM This strips all quotes from VAR:
ECHO !VAR:^"=!
REM Really that it.
Чтобы вырезать кавычки из текстового файла или выход команды, все будет усложняться, потому что с Delayed Expansion строка типа !VAR!
в текстовом документе будет расширяться (в рамках расширения %%i
в FOR /F
), когда это не должно. (Это еще одно раскрытие информации об уязвимости - это не описано в другом месте.)
Чтобы безопасно проанализировать документ, необходим переход между средой с задержкой расширения и средой с расширением.
REM Suppose we fetch the text from text.txt
SETLOCAL DisableDelayedExpansion
REM The FOR options here employs a trick to disable both "delims"
REM characters (i.e. field separators) and "eol" character (i.e. comment
REM character).
FOR /F delims^=^ eol^= %%L IN (text.txt) DO (
REM This expansion is safe because cmd.exe expands %%L after quotes
REM parsing as long as DelayedExpansion is Disabled. Even when %%L
REM can contain quotes, carets and exclamation marks.
SET "line=%%L"
CALL :strip_quotes
REM Print out the result. (We can't use !line! here without delayed
REM expansion, so do so in a subroutine.)
CALL :print_line
)
ENDLOCAL
GOTO :EOF
REM Reads !line! variable and strips quotes from it.
:strip_quotes
SETLOCAL EnableDelayedExpansion
SET line=!line:^"=!
REM Make the variable out of SETLOCAL
REM I'm expecting you know how this works:
REM (You may use ampersand instead:
REM `ENDLOCAL & SET "line=%line%"`
REM I just present another way that works.)
(
ENDLOCAL
SET "line=%line%"
)
GOTO :EOF
:print_line
SETLOCAL EnableDelayedExpansion
ECHO !line!
ENDLOCAL
GOTO :EOF
delims^=^ eol^=
в приведенном выше коде, вероятно, нуждается в объяснении:
Это эффективно отключает символы "делимы" (например, разделители полей) и "eol" (т.е. Символ комментария). Без этого "delims" по умолчанию будет иметь вкладку и пробел, а "eol" по умолчанию - точку с запятой.
- Значок
eol=
всегда читает любой символ после знака равенства. Чтобы отключить его, этот токен должен быть в конце строки параметров, чтобы ни один символ не мог использоваться для "eol" , эффективно отключив его. Если строка опций цитируется, она может использовать кавычку ( ") как" eol ", поэтому мы не должны приводить строку опций.
- Опция
delims=
, когда она не является последней опцией в строке параметров, будет прервана пробелом. (Чтобы включить пробел в "delims" , он должен быть последним вариантом опций FOR /F
.) Итак, delims=
, за которым следует пробел, а затем другой параметр отключает "delims" .
Ответ 5
Это превратит "C:\Program Files\somefile.txt"
в C:\Program Files\somefile.txt
сохраняя при этом такие случаи, как Height=5'6"
и Symbols="[email protected]#
:DeQuote
SET _DeQuoteVar=%1
CALL SET _DeQuoteString=%%!_DeQuoteVar!%%
IF [!_DeQuoteString:~0^,1!]==[^"] (
IF [!_DeQuoteString:~-1!]==[^"] (
SET _DeQuoteString=!_DeQuoteString:~1,-1!
) ELSE (GOTO :EOF)
) ELSE (GOTO :EOF)
SET !_DeQuoteVar!=!_DeQuoteString!
SET _DeQuoteVar=
SET _DeQuoteString=
GOTO :EOF
Пример
SetLocal EnableDelayedExpansion
set _MyVariable = "C:\Program Files\ss64\"
CALL :dequote _MyVariable
echo %_MyVariable%
Ответ 6
В приведенном выше ответе (начиная с: DeQuote) предполагается, что расширение переменной среды с задержкой включено. Из cmd/?:
Отложенное расширение переменной среды НЕ включено по умолчанию. Вы
может включать или отключать задержку изменения переменной среды для
конкретный вызов CMD.EXE с помощью переключателя /V: ON или /V: OFF. Вы
может включать или отключать завершение для всех вызовов CMD.EXE на
сеанса входа в систему и/или пользователя, установив один или оба из
после значений REG_DWORD в реестре с помощью REGEDT32.EXE:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\DelayedExpansion
and/or
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\DelayedExpansion
либо 0x1, либо 0x0. Пользовательский параметр имеет приоритет над
установка машины. Переключатели командной строки имеют приоритет над
настройки реестра.
Если расширенное расширение переменной среды включено, тогда восклицательный знак
символ может использоваться для замены значения переменной среды
во время выполнения.
Ответ 7
Следующий командный файл запускает серию программ с задержкой после каждого из них.
Проблема заключается в передаче командной строки с параметрами для каждой программы. Для этого требуются котировки вокруг аргумента программы, которые удаляются при вызове. Это иллюстрирует несколько методов обработки пакетных файлов.
Посмотрите на локальную подпрограмму: mystart, как передается аргумент в кавычках, и кавычки удаляются.
@echo off
rem http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/if.mspx?mfr=true
rem Start programs with delay
rem Wait n seconds
rem n number retries to communicate with the IP address
rem 1000 milliseconds between the retries
rem 127.0.0.1 is the LocalHost
rem start /b (silent) /min (minimized) /belownormal (lower priority)
rem /normal provides a no-op switch to hold the place of argument 1
rem start /normal "Opinions" %SystemRoot%\explorer.exe /e,d:\agar\jobs\opinion
rem ping 127.0.0.1 -n 8 -w 1000 > nul
rem Remove quotes in Batch
rem http://ss64.com/nt/syntax-dequote.html
rem String manipulation in Batch
rem http://www.dostips.com/DtTipsStringManipulation.php
rem ^ line continuation
rem
rem set p="One Two" p has the exact value "One Two" including the quotes
rem set p=%p:~1,-1% Removes the first and last characters
rem set p=%p:"=% Removes all double-quotes
rem set p=%p:cat=mouse% Replaces cat with mouse
rem ping 127.0.0.1 -n 12 -w 1000 > nul
rem 1 2 3 4
@echo on
call :mystart /b/min "Opinions" "%SystemRoot%\explorer.exe /e,d:\agar\jobs\opinion" 8
@echo on
call :mystart /b/min "Notepad++" D:\Prog_D\Notepad++\notepad++.exe 14
@echo on
call :mystart /normal "Firefox" D:\Prog_D\Firefox\firefox.exe 20
@rem call :mystart /b/min "ProcessExplorer" D:\Prog_D\AntiVirus\SysInternals\procexp.exe 8
@echo on
call :mystart /b/min/belownormal "Outlook" D:\Prog_D\MSOffice\OFFICE11\outlook.exe 2
@echo off
goto:eof
:mystart
@echo off
rem %3 is "program-path arguments" with the quotes. We remove the quotes
rem %4 is seconds to wait after starting that program
set p=%3
set p=%p:"=%
start %1 %2 %p%
ping 127.0.0.1 -n %4 -w 1000 > nul
goto:eof
Ответ 8
Метод грубой силы:
echo "foo <3 bar" | sed -e 's/\(^"\|"$\)//g'
Для этого нужно найти подходящую версию Win32 sed
, конечно.
Ответ 9
Использование команды FOR для разделения окружающих кавычек является наиболее эффективным способом, который я нашел для этого. В компактной форме (пример 2) это однострочный.
Пример 1: 5-строчное (прокомментированное) решение.
REM Set your string
SET STR=" <output file> (Optional) If specified this is the name of your edited file"
REM Echo your string into the FOR loop
FOR /F "usebackq tokens=*" %%A IN (`ECHO %STR%`) DO (
REM Use the "~" syntax modifier to strip the surrounding quotation marks
ECHO %%~A
)
Пример 2: пример реального уровня в 1 строке.
SET STR=" <output file> (Optional) If specified this is the name of your edited file"
FOR /F "usebackq tokens=*" %%A IN (`ECHO %STR%`) DO @ECHO %%~A
Мне интересно, что внутреннее эхо игнорирует символы переадресации '<' и ' > '.
Если вы выполните ECHO asdfsd>asdfasd
, вы выберете файл вместо outd out.
Надеюсь, что это поможет:)
Edit:
Я подумал об этом и понял, что есть еще более простой (и менее хакерский) способ сделать то же самое. Используйте расширенную замену/расширение переменных (см. HELP SET
) следующим образом:
SET STR=" <output file> (Optional) If specified this is the name of your edited file"
ECHO %STR:~1,-1%
Это будет печатать все, кроме первого и последнего символов (ваши кавычки). Я бы рекомендовал использовать SETLOCAL ENABLEDELAYEDEXPANSION
тоже. Если вам нужно выяснить, где кавычки находятся в строке, вы можете использовать FINDSTR для получения символа #s.
Ответ 10
Я знаю, что на самом деле это не для автора, но если вам нужно отправить какой-то текст в файл без кавычек - ниже будет работать решение для меня. Вам не нужно использовать кавычки в команде echo, просто окружите полную команду скобками.
(
echo first very long line
echo second very long line with %lots% %of% %values%
) >"%filename%"
Ответ 11
http://unxutils.sourceforge.net/ - это родной порт win32 из множества утилит GNU, включая sed, gawk, grep и wget. (извините, что мне не хватает репутации, чтобы опубликовать это как комментарий!)