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.
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.
Vous pouvez utiliser le %var:x=y%
construction qui remplace tout x
y
.
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%
l'approche suivante peut être utilisée pour imprimer une chaîne sans guillemets:
echo|set /p="<h1>Hello</h1>"
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 deFOR /F
options.), Doncdelims=
suivi d'un espace puis une autre option désactive le "delims".
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%
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.
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
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.
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.
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%"
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!)