Comment supprimer des citations D'une chaîne ECHO dans un fichier Windows batch?

J'ai un fichier Windows batch que je crée, mais je dois faire écho à une grande chaîne complexe, donc je dois mettre des guillemets doubles de chaque côté. Le problème est que les citations se répercutent aussi sur le fichier auquel je l'écris. Comment faire écho à une telle corde et enlever les citations?

mise à jour:

j'ai passé les deux derniers jours à travailler là-dessus et j'ai finalement pu faire quelque chose ensemble. La réponse de Richard a fonctionné pour enlever les citations, mais même quand J'ai mis L'écho dans le sous-programme et que j'ai sorti directement la corde, les fenêtres étaient accrochées aux chars dans la corde. J'accepte la réponse de Richard puisqu'elle répond à la question posée.

J'ai fini par utiliser la solution sed de Greg, mais j'ai dû la modifier à cause de bogues/fonctionnalités sed/windows (cela ne m'a pas aidé qu'elle soit fournie sans documentation). Il ya quelques mises en garde à l'utilisation de sed dans Windows: vous devez utiliser des guillemets doubles au lieu de guillemets simples, vous ne pouvez pas échapper à la double guillemets dans la chaîne directement, vous devez endquote la chaîne, s'échapper en utilisant le ^ (so^") puis beqin quote pour la section suivante. En outre, quelqu'un a souligné que si vous pipe input to sed, il y a un bug avec un tuyau étant dans la chaîne (je n'ai pas eu à vérifier cela car dans ma solution finale, je viens de trouver un moyen de ne pas avoir toutes les citations au milieu de la chaîne, et juste enlevé toutes les citations, Je n'ai jamais réussi à faire enlever l'endquote par lui-même.) Merci pour toute l'aide.

37
demandé sur Lance Roberts 2009-04-30 02:56:41

11 réponses

cette fonctionnalité est intégrée à la commande call. Pour citer l'aide de l'appel:

 Substitution of batch parameters (%n) has been enhanced.  You can
 now use the following optional syntax:

 %~1         - expands %1 removing any surrounding quotes (")

voici un exemple primitif:

@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

Sortie:

C:\>dequote
mystring="this is some quoted text"
ret=this is some quoted text

je devrais crédit de la "variable d'environnement tunneling' technique (endlocal&set ret=%thestring%) de Tim Hill, 'Windows NT Shell Scripting'. C'est le seul livre que j'ai jamais trouvé qui s'adresse aux fichiers batch avec n'importe quelle profondeur.

52
répondu Richard A 2009-04-30 00:01:18

Vous pouvez utiliser le %var:x=y% construction qui remplace tout xy.

voir cet exemple ce qu'il peut faire:

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%
10
répondu Big Joe 2012-10-05 08:08:53

l'approche suivante peut être utilisée pour imprimer une chaîne sans guillemets:

echo|set /p="<h1>Hello</h1>"
4
répondu Daniel Budzyński 2016-12-22 01:43:58

pour supprimer tous les guillemets d'une variable définie, Vous avez besoin D'une extension de Variable retardée pour étendre la variable en toute sécurité et la traiter. L'Expansion à l'aide de signes de pourcentage (c'est à dire %VAR% et %1) sont intrinsèquement dangereux (ils sont vulnérables à la commande d'injection; lire ceci pour plus de détails).

SETLOCAL EnableDelayedExpansion
SET VAR=A ^"quoted^" text.
REM This strips all quotes from VAR:
ECHO !VAR:^"=!
REM Really that's it.

pour supprimer des guillemets d'un fichier texte ou d'une sortie de commande, les choses vont se compliquer car avec une extension retardée, une chaîne comme !VAR! dans le texte document permettra d'obtenir étendue (dans le %%i extension FOR /F) quand il ne devrait pas. (Il s'agit d'une autre vulnérabilité-divulgation d'information-qui n'est pas documentée ailleurs.)

pour analyser le document en toute sécurité, il faut passer d'un environnement à extension retardée à un environnement à désactivation.

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^= dans le code ci-dessus nécessite probablement une explication: Cela supprime effectivement les caractères " delims "(c.-à-d. séparateurs de champ) et" eol " (c.-à-d. caractère de commentaire). Sans lui, le" delims "sera par défaut à tab et l'espace et" eol " par défaut à un point-virgule.

  • eol= token toujours lire quel que soit le caractère suivant il est après le signe égal. Pour désactiver ce jeton doit être à la fin de la chaîne d'options de sorte qu'aucun caractère ne peut être utilisé pour "eol", effectivement en le désactivant. Si la chaîne d'options est citée, elle peut utiliser le guillemet ( ") comme" fin de liste", nous ne devons donc pas citer les options chaîne.
  • delims= option, quand ce n'est pas la dernière option dans la chaîne options, sera terminée par un espace. (Pour inclure l'espace dans "delims" il doit être la dernière option de FOR /F options.), Donc delims= suivi d'un espace puis une autre option désactive le "delims".
3
répondu Explorer09 2017-05-15 16:48:25

Ce tout en préservant des cas tels que Height=5'6" et Symbols="!@#

: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

Exemple

SetLocal EnableDelayedExpansion
set _MyVariable = "C:\Program Files\ss64\"
CALL :dequote _MyVariable
echo %_MyVariable%
2
répondu JRL 2009-04-29 23:17:08

la réponse ci-dessus (en commençant par :DeQuote) suppose que l'expansion de la variable d'environnement est réglée sur on. De cmd/?:

Delayed environment l'extension de la variable d'environnement n'est pas activée par défaut. Vous peut activer ou désactiver l'extension de variable d'environnement différé pour un invocation particulière du CMD.EXE avec l'interrupteur /V:ON ou /V:OFF. Vous peut activer ou désactiver la completion pour toutes les invocations de CMD.EXE on a machine et / ou session d'ouverture de session de l'utilisateur en réglant l'un ou l'autre ou les deux suivant REG_DWORD values in the registry using REGEDT32.EXE:

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\DelayedExpansion

    and/or

HKEY_CURRENT_USER\Software\Microsoft\Command Processor\DelayedExpansion

à la valeur 0x1 ou 0x0. L'utilisateur paramètre spécifique l'emporte sur le paramètre de la machine. Les commutateurs de ligne de commande prévalent sur les les paramètres du registre.

si l'extension de la variable d'environnement retardée est activée, alors l'exclamation caractère qui peut être utilisé pour remplacer la valeur d'une variable d'environnement au moment de l'exécution.

2
répondu james 2009-04-29 23:41:37

le fichier batch suivant démarre une série de programmes avec un retard après chacun.

le problème est de passer une ligne de commande avec des paramètres pour chaque programme. Cela nécessite des guillemets autour du programme de l'argument, qui sont supprimés lorsque l'appel est effectué. Ceci illustre quelques techniques dans le traitement de fichiers par lots.

regardez dans le sous-programme local :mystart pour savoir comment un argument entre guillemets est passé, et les guillemets sont supprimés.

@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
2
répondu Andrew_M_Garland 2012-04-22 15:44:25

la force Brute de la méthode:

echo "foo <3 bar" | sed -e 's/\(^"\|"$\)//g'

cela nécessite de trouver une version Win32 appropriée de sed, bien sûr.

1
répondu Greg Hewgill 2009-04-29 23:02:52

L'utilisation de la commande FOR pour enlever les guillemets environnants est la façon la plus efficace que j'ai trouvée de faire ceci. Sous la forme compacte (exemple 2), c'est une doublure unique.

exemple 1: la solution à 5 lignes (commentée).

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
)

exemple 2: l'exemple 1-liner du monde réel.

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

je trouve intéressant que l'écho interne ignore les caractères de redirection '<' et '>'.

Si vous exécutez ECHO asdfsd>asdfasd vous écrirez le fichier au lieu de MST out.

Espérons que cela aide :)

Edit:

j'y ai réfléchi et j'ai réalisé qu'il y avait une façon encore plus facile (et moins hacky) d'accomplir la même chose. Utilisez la variable améliorée substitution / expansion (voir HELP SET) comme ceci:

SET STR=" <output file>    (Optional) If specified this is the name of your edited file"

ECHO %STR:~1,-1%

qui affichera tous les caractères sauf le premier et le dernier (vos guillemets). Je vous conseille d'utiliser SETLOCAL ENABLEDELAYEDEXPANSION trop. Si vous avez besoin de comprendre où les guillemets sont situés la chaîne que vous pouvez utiliser FINDSTR pour obtenir le caractère #s.

1
répondu TwoByteHero 2013-03-20 04:51:54

je sais qu'il n'est pas fait pour l'auteur, mais si vous avez besoin d'envoyer du texte le fichier sans les guillemets - la solution ci-dessous fonctionne pour moi. Vous n'avez pas besoin d'utiliser des guillemets dans l'écho de commande, il suffit d'entourer la commande complète avec des crochets.

(
    echo first very long line
    echo second very long line with %lots% %of% %values%
) >"%filename%"
1
répondu cyber_by 2015-05-29 14:35:52

http://unxutils.sourceforge.net/ est un port win32 natif d'un groupe D'utilitaires GNU incluant sed, gawk, grep et wget. (désolé que je n'ai pas assez de rep à la poste comme un commentaire!)

0
répondu fearoffours 2009-04-29 23:11:41