Как вы вырезаете кавычки из строки 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. (извините, что мне не хватает репутации, чтобы опубликовать это как комментарий!)