templates - ¿heredoc para lote de Windows?
batch-file (17)
¿Hay alguna manera de especificar cadenas de varias líneas en lote de una manera similar a heredoc en shells de Unix. Algo similar a:
cat <<EOF > out.txt
bla
bla
..
EOF
La idea es crear un archivo personalizado a partir de un archivo de plantilla.
@jeb
setlocal EnableDelayedExpansion
set LF=^
REM Two empty lines are required
otra variante
@echo off
:)
setlocal enabledelayedexpansion
>nul,(pause&set /p LF=&pause&set /p LF=)<%0
set LF=!LF:~0,1!
echo 1!LF!2!LF!3
pause
Ampliando en ephemient post, que creo que es el mejor, lo siguiente hará una pipa:
(
@echo.line1
@echo.line2 %time% %os%
@echo.
@echo.line4
) | more
En la publicación de ephemient redirigió al principio, que es un estilo agradable, pero también se puede redirigir al final como tal:
(
@echo.line1
@echo.line2 %time% %os%
@echo.
@echo.line4
) >C:/Temp/test.txt
Tenga en cuenta que "@echo". nunca se incluye en la salida y "@echo". por sí mismo da una línea en blanco.
Aquí hay otro enfoque.
@echo off
:: ######################################################
:: ## Heredoc syntax: ##
:: ## call :heredoc uniqueIDX [>outfile] && goto label ##
:: ## contents ##
:: ## contents ##
:: ## contents ##
:: ## etc. ##
:: ## :label ##
:: ## ##
:: ## Notes: ##
:: ## Variables to be evaluated within the heredoc ##
:: ## should be called in the delayed expansion style ##
:: ## (!var! rather than %var%, for instance). ##
:: ## ##
:: ## Literal exclamation marks (!) and carats (^) ##
:: ## must be escaped with a carat (^). ##
:: ######################################################
:--------------------------------------------
: calling heredoc with results sent to stdout
:--------------------------------------------
call :heredoc stickman && goto next1
/o/
| This is the "stickman" heredoc, echoed to stdout.
/ /
:next1
:-----------------------------------------------------------------
: calling heredoc containing vars with results sent to a text file
:-----------------------------------------------------------------
set bodyText=Hello world!
set lipsum=Lorem ipsum dolor sit amet, consectetur adipiscing elit.
call :heredoc html >out.txt && goto next2
<html lang="en">
<body>
<h3>!bodyText!</h3>
<p>!lipsum!</p>
</body>
</html>
Thus endeth the heredoc. :)
:next2
echo;
echo Does the redirect to a file work? Press any key to type out.txt and find out.
echo;
pause>NUL
type out.txt
del out.txt
:: End of main script
goto :EOF
:: ########################################
:: ## Here''s the heredoc processing code ##
:: ########################################
:heredoc <uniqueIDX>
setlocal enabledelayedexpansion
set go=
for /f "delims=" %%A in (''findstr /n "^" "%~f0"'') do (
set "line=%%A" && set "line=!line:*:=!"
if defined go (if #!line:~1!==#!go::=! (goto :EOF) else echo(!line!)
if "!line:~0,13!"=="call :heredoc" (
for /f "tokens=3 delims=>^ " %%i in ("!line!") do (
if #%%i==#%1 (
for /f "tokens=2 delims=&" %%I in ("!line!") do (
for /f "tokens=2" %%x in ("%%I") do set "go=%%x"
)
)
)
)
)
goto :EOF
Ejemplo de salida:
C:/Users/oithelp/Desktop>heredoc
/o/
| This is the "stickman" heredoc, echoed to stdout.
/ /
Does the redirect to a file work? Press any key to type out.txt and find out.
<html lang="en">
<body>
<h3>Hello world!</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</body>
</html>
Thus endeth the heredoc. :)
Aquí hay una variante de la excelente solución de ephemient. Esto le permite canalizar varias líneas a otro programa sin crear realmente un archivo de texto e ingresarlo redirigiéndolo a su programa:
(@echo.bla
@echo.bla
) | yourprog.exe
Para un ejemplo rápido y funcional, puede reemplazar yourprog.exe
con more
:
(@echo.bla
@echo.bla
) | more
Salida:
bla
bla
El uso de una macro con parámetros permite escribir un "heredoc" de una manera más simple:
@echo off
rem Definition of heredoc macro
setlocal DisableDelayedExpansion
set LF=^
::Above 2 blank lines are required - do not remove
set ^"/n=^^^%LF%%LF%^%LF%%LF%^^"
set heredoc=for %%n in (1 2) do if %%n==2 (%/n%
for /F "tokens=1,2" %%a in ("!argv!") do (%/n%
if "%%b" equ "" (call :heredoc %%a) else call :heredoc %%a^>%%b%/n%
endlocal ^& goto %%a%/n%
)%/n%
) else setlocal EnableDelayedExpansion ^& set argv=
rem Heredoc syntax:
rem
rem %%heredoc%% :uniqueLabel [outfile]
rem contents
rem contents
rem ...
rem :uniqueLabel
rem
rem Same notes of rojo''s answer apply
rem Example borrowed from rojo''s answer:
set bodyText=Hello world!
set lipsum=Lorem ipsum dolor sit amet, consectetur adipiscing elit.
%heredoc% :endHtml out.txt
<html lang="en">
<body>
<h3>!bodyText!</h3>
<p>!lipsum!</p>
</body>
</html>
:endHtml
echo File created:
type out.txt
del out.txt
goto :EOF
rem Definition of heredoc subroutine
:heredoc label
set "skip="
for /F "delims=:" %%a in (''findstr /N "%1" "%~F0"'') do (
if not defined skip (set skip=%%a) else set /A lines=%%a-skip-1
)
for /F "skip=%skip% delims=" %%a in (''findstr /N "^" "%~F0"'') do (
set "line=%%a"
echo(!line:*:=!
set /A lines-=1
if !lines! == 0 exit /B
)
exit /B
En DosTips, siberia-man publicó una demostración del comportamiento sorprendente de una declaración GOTO errónea en la forma de (goto) 2>nul
. Aacini y jeb luego documentaron algunos descubrimientos adicionales interesantes sobre el comportamiento extraño. Básicamente se comporta como una EXIT /B
, excepto que permite ejecutar comandos concatenados dentro de una rutina LLAMADA en el contexto de la persona que llama principal.
Aquí hay una breve secuencia de comandos que demuestra la mayoría de los puntos destacados:
@echo off
setlocal enableDelayedExpansion
set "var=Parent Value"
(
call :test
echo This and the following line are not executed
exit /b
)
:break
echo How did I get here^^!^^!^^!^^!
exit /b
:test
setlocal disableDelayedExpansion
set "var=Child Value"
(goto) 2>nul & echo var=!var! & goto :break
echo This line is not executed
:break
echo This line is not executed
- SALIDA -
var=Parent Value
How did I get here!!!!
Este comportamiento increíble me ha permitido escribir una elegante emulación por lotes de un documento aquí con muchas de las opciones disponibles para Unix. Implementé PrintHere.bat como una utilidad independiente que debe colocarse en una carpeta incluida en tu PATH. Entonces, cualquier secuencia de comandos por lotes puede LLAMAR con facilidad la utilidad para obtener la funcionalidad doc aquí.
Aquí está la sintaxis general de uso:
call PrintHere :Label
Here doc text goes here
:Label
¿Cómo se puede lograr esto? ... Mi utilidad PrintHere usa el truco (GOTO) 2>nul
dos veces.
La primera vez que uso
(GOTO) 2>nul
para regresar a la persona que llama, así puedo obtener la ruta completa al script de llamada para que PrintHere sepa de qué archivo leer. ¡Entonces LLAMO A Imprimir por segunda vez!La segunda vez uso
(GOTO) 2>nul
para regresar a la persona que llama y GOTO la etiqueta de terminación para que no se ejecute el texto de doc aquí.
Nota: el siguiente script contiene un carácter de tabulación (0x09) en la definición de pestaña, directamente debajo de la etiqueta :start
. Algunos navegadores pueden tener dificultades para mostrar y copiar la pestaña. Como alternativa, puede descargar PrintHere.bat.txt desde mi Dropbox , y simplemente renombrarlo como PrintHere.bat.
Originalmente publiqué PrintHere.bat en DosTips , donde puede realizar un seguimiento del desarrollo futuro.
PrintHere.bat
@echo off & setlocal disableDelayedExpansion & goto :start
::PrintHere.bat version 1.1 by Dave Benham
:::
:::call PrintHere [/E] [/- "TrimList"] :Label ["%~f0"]
:::call PrintHere [/E] [/- "TrimList"] :Label "%~f0" | someCommand & goto :Label
:::PrintHere /?
:::PrintHere /V
:::
::: PrintHere.bat provides functionality similar to the unix here doc feature.
::: It prints all content between the CALL PrintHere :Label line and the
::: terminating :Label. The :Label must be a valid label supported by GOTO, with
::: the additional constraint that it not contain *. Lines are printed verbatim,
::: with the following exceptions and limitations:
:::
::: - Lines are lmited to 1021 bytes long
::: - Trailing control characters are stripped from each line
:::
::: The code should look something like the following:
:::
::: call PrintHere :Label
::: Spacing and blank lines are preserved
:::
::: Special characters like & < > | ^ ! % are printed normally
::: :Label
:::
::: If the /E option is used, then variables between exclamation points are
::: expanded, and ! and ^ literals must be escaped as ^! and ^^. The limitations
::: are different when /E is used:
:::
::: - Lines are limited to ~8191 bytes long
::: - All characters are preserved, except !variables! are expanded and ^! and
::: ^^ are transformed into ! and ^
:::
::: Here is an example using /E:
:::
::: call PrintHere /E :SubstituteExample
::: Hello !username!^!
::: :SubstituteExample
:::
::: If the /- "TrimList" option is used, then leading "TrimList" characters
::: are trimmed from the output. The trim characters are case sensitive, and
::: cannot include a quote. If "TrimList" includes a space, then it must
::: be the last character in the list.
:::
::: Multiple PrintHere blocks may be defined within one script, but each
::: :Label must be unique within the file.
:::
::: PrintHere must not be used within a parenthesized code block.
:::
::: Scripts that use PrintHere must use /r/n for line termination, and all lines
::: output by PrintHere will be terminated by /r/n.
:::
::: All redirection associated with a PrintHere must appear at the end of the
::: command. Also, the CALL can include path information:
:::
::: call "c:/utilities/PrintHere.bat" :MyBlock>test.txt
::: This line is written to test.txt
::: :MyBlock
:::
::: PrintHere may be used with a pipe, but only on the left side, and only
::: if the source script is included as a 2nd argument, and the right side must
::: explicitly and unconditionally GOTO the terminating :Label.
:::
::: call PrintHere :PipedBlock "%~f0" | more & goto :PipedBlock
::: text goes here
::: :PipedBlock
:::
::: Commands concatenated after PrintHere are ignored. For example:
:::
::: call PrintHere :ignoreConcatenatedCommands & echo This ECHO is ignored
::: text goes here
::: :ignoreConcatenatedCommands
:::
::: PrintHere uses FINDSTR to locate the text block by looking for the
::: CALL PRINTHERE :LABEL line. The search string length is severely limited
::: on XP. To minimize the risk of PrintHere failure when running on XP, it is
::: recommended that PrintHere.bat be placed in a folder included within PATH
::: so that the utility can be called without path information.
:::
::: PrintHere /? prints out this documentation.
:::
::: PrintHere /V prints out the version information
:::
::: PrintHere.bat was written by Dave Benham. Devlopment history may be traced at:
::: http://www.dostips.com/forum/viewtopic.php?f=3&t=6537
:::
:start
set "tab= " NOTE: This value must be a single tab (0x09), not one or more spaces
set "sp=[ %tab%=,;]"
set "sp+=%sp%%sp%*"
set "opt="
set "/E="
set "/-="
:getOptions
if "%~1" equ "" call :exitErr Invalid call to PrintHere - Missing :Label argument
if "%~1" equ "/?" (
for /f "tokens=* delims=:" %%L in (''findstr "^:::" "%~f0"'') do echo(%%L
exit /b 0
)
if /i "%~1" equ "/V" (
for /f "tokens=* delims=:" %%L in (''findstr /rc:"^::PrintHere/.bat version" "%~f0"'') do echo(%%L
exit /b 0
)
if /i %1 equ /E (
set "/E=1"
set "opt=%sp+%.*"
shift /1
goto :getOptions
)
if /i %1 equ /- (
set "/-=%~2"
set "opt=%sp+%.*"
shift /1
shift /1
goto :getOptions
)
echo %1|findstr "^:[^:]" >nul || call :exitErr Invalid PrintHere :Label
if "%~2" equ "" (
(goto) 2>nul
setlocal enableDelayedExpansion
if "!!" equ "" (
endlocal
call %0 %* "%%~f0"
) else (
>&2 echo ERROR: PrintHere must be used within a batch script.
(call)
)
)
set ^"call=%0^"
set ^"label=%1^"
set "src=%~2"
setlocal enableDelayedExpansion
set "call=!call:/=[//]!"
set "label=!label:/=[//]!"
for %%C in (. [ $ ^^ ^") do (
set "call=!call:%%C=/%%C!"
set "label=!label:%%C=/%%C!"
)
set "search=!sp!*call!sp+!!call!!opt!!sp+!!label!"
set "cnt="
for /f "delims=:" %%N in (''findstr /brinc:"!search!$" /c:"!search![<>|&!sp:~1!" "!src!"'') do if not defined skip set "skip=%%N"
if not defined skip call :exitErr Unable to locate CALL PrintHere %1
for /f "delims=:" %%N in (''findstr /brinc:"!sp!*!label!$" /c:"!sp!*!label!!sp!" "!src!"'') do if %%N gtr %skip% if not defined cnt set /a cnt=%%N-skip-1
if not defined cnt call :exitErr PrintHere end label %1 not found
if defined /E (
for /f "skip=%skip% delims=" %%L in (''findstr /n "^^" "!src!"'') do (
if !cnt! leq 0 goto :break
set "ln=%%L"
if not defined /- (echo(!ln:*:=!) else for /f "tokens=1* delims=%/-%" %%A in (^""%/-%!ln:*:=!") do (
setlocal disableDelayedExpansion
echo(%%B
endlocal
)
set /a cnt-=1
)
) else (
for /l %%N in (1 1 %skip%) do set /p "ln="
for /l %%N in (1 1 %cnt%) do (
set "ln="
set /p "ln="
if not defined /- (echo(!ln!) else for /f "tokens=1* delims=%/-%" %%A in (^""%/-%!ln!") do (
setlocal disableDelayedExpansion
echo(%%B
endlocal
)
)
) <"!src!"
:break
(goto) 2>nul & goto %~1
:exitErr
>&2 echo ERROR: %*
(goto) 2>nul & exit /b 1
La documentación completa está integrada en el script. A continuación se muestran algunas demostraciones de uso:
Salida literal
@echo off
call PrintHere :verbatim
Hello !username!^!
It is !time! on !date!.
:verbatim
- SALIDA -
Hello !username!^!
It is !time! on !date!.
Expandir variables (no es necesario habilitar la expansión retrasada)
@echo off
call PrintHere /E :Expand
Hello !username!^!
It is !time! on !date!.
:Expand
--SALIDA--
Hello Dave!
It is 20:08:15.35 on Fri 07/03/2015.
Expandir variables y recortar espacios iniciales
@echo off
call PrintHere /E /- " " :Expand
Hello !username!^!
It is !time! on !date!.
:Expand
--SALIDA--
Hello Dave!
It is 20:10:46.09 on Fri 07/03/2015.
La salida se puede redirigir a un archivo
@echo off
call PrintHere :label >helloWorld.bat
@echo Hello world!
:label
La salida no se puede redireccionar como entrada, ¡pero se puede canalizar! Desafortunadamente, la sintaxis no es tan elegante porque ambos lados de un conducto se ejecutan en un nuevo proceso CMD.EXE , por lo que (GOTO) 2>nul
regresa a un proceso cmd secundario, y no al script maestro.
@echo off
call PrintHere :label "%~f0" | findstr "^" & goto :label
Text content goes here
:label
En un makefile de Microsoft NMake, se pueden usar heredores de UNIX verdaderos, tal como el propietario del hilo los solicitó. Por ejemplo, esta es una regla explícita para crear un archivo Deploy.sed :
Deploy.sed:
type << >$@
; -*-ini-generic-*-
;
; Deploy.sed -- Self-Extracting Directives
;
[Version]
Class=IEXPRESS
SEDVersion=3
.
.
[Strings]
InstallPrompt=Install $(NAME)-$(VERSION).xll to your personal XLSTART directory?
DisplayLicense=H:/prj/prog/XLL/$(NAME)/README.txt
.
.
<<
clean:
-erase /Q Deploy.sed
donde << se expande en un nombre de archivo temporal que NMake crea sobre la marcha al ejecutar la regla. Es decir, cuando Deploy.sed no existe. Lo bueno es que las variables de NMake también se expanden (aquí las variables NOMBRE y VERSIÓN ). Guarde esto como archivo MAKE . Abra un DOS-box en el directorio de makefile y use:
> nmake Deploy.sed
para crear el archivo, y:
> nmake clean
para eliminarlo NMake es parte de todas las versiones de Visual Studio C ++, incluidas las ediciones Express.
Esto es aún más fácil, y se asemeja mucho a cat << EOF> out.txt:
C: /> copiar con out.txt
Esta es mi primera línea de texto.
Esta es mi última línea de texto.
^ Z
1 archivo (s) copiados.
La salida se ve así:
C: /> escriba out.txt
Esta es mi primera línea de texto.
Esta es mi última línea de texto.
(copie con + out.txt, escriba su entrada, seguido de Ctrl-Z y el archivo se copiará)
COPY CON significa "copiar desde la consola" (aceptar la entrada del usuario)
Lo que OP deseaba era algo muy específico (crear un archivo de texto con el resultado) y la respuesta aceptada lo hace perfectamente, pero la solución presentada no funciona bien fuera de ese contexto específico. Por ejemplo, si quiero pasar entrada de varias líneas a un comando, no puedo usar la sintaxis ( echo )
. Esto es lo que terminó funcionando para mí.
Dado un script perl llamado "echolines.pl" que consiste en lo siguiente (para simular un programa "real"):
use strict;
use warnings;
while (<>) {
chomp;
print qq(<$_>/n);
}
y un archivo por lotes llamado "testme.bat" que contiene:
@echo off
set FOO=foo
set BAR=bar
set BAZ=baz
echo %FOO%^
&echo %BAR%^
&echo %BAZ%|perl echolines.pl
ejecutarlo produce el resultado esperado:
C:/>testme
<foo>
<bar>
<baz>
Se debe tener cuidado con el espacio en blanco para garantizar que todo funcione correctamente sin espacios perdidos en ningún lado. Específicamente: cada final de línea debe ser un símbolo de intercalación (^) seguido de una línea nueva, las líneas subsiguientes deben comenzar inmediatamente con el signo & (y) y la última línea debe tener el tubo comenzando inmediatamente después del último elemento enviado. De lo contrario, se perderán los parámetros o espacios en blanco adicionales antes y después de los parámetros.
No tan lejos como sé.
Lo más cercano que sé es
> out.txt (
@echo.bla
@echo.bla
...
)
( @
evita que el propio shell de comando imprima los comandos que está ejecutando, y echo.
permite comenzar una línea con un espacio).
Prueba este código (El código de JScript en la parte inferior escribe "out.html" en el disco)
@if(0)==(0) echo on
cscript.exe //nologo //E:JScript "%~f0" source1 out.html
start out.html
goto :EOF
[source1]
<!DOCTYPE html>
<html>
<head>
title></title>
</head>
<body>
<svg width="900" height="600">
<text x="230"
y="150"
font-size="100"
fill="blue"
stroke="gray"
stroke-width="1">
Hello World
</text>
</svg>
</body>
</html>
[/source1]
@end
if (WScript.Arguments.length != 2) WScript.Quit();
var tagName = WScript.Arguments(0);
var path = WScript.Arguments(1);
var startTag = "[" + tagName + "]"
var endTag = "[/" + tagName + "]"
var fso = new ActiveXObject("Scripting.FileSystemObject");
var file1 = fso.OpenTextFile(WScript.ScriptFullName);
var txt = "";
var found = false;
while (!file1.AtEndOfStream) {
var line = file1.ReadLine();
if (!found) {
if (line.lastIndexOf(startTag, 0) === 0) found = true;
} else {
if (line.lastIndexOf(endTag, 0) === 0) break;
txt += line + "/n";
}
}
file1.Close();
var file2 = fso.CreateTextFile(path, true, false);
file2.Write(txt);
file2.Close();
Puede crear un bloque de texto entrecomillado con un bucle FOR / F, por lo que no necesitó escapar de caracteres especiales como <>|&
solo se debe escapar de %
.
Esto a veces es útil, como crear un resultado html.
@echo off
setlocal EnableDelayedExpansion
set LF=^
REM Two empty lines are required
set ^"NL=^^^%LF%%LF%^%LF%%LF%^^"
for /F "tokens=* delims=_" %%a in (^"%NL%
___"One<>&|"%NL%
___"two 100%%"%NL%
___%NL%
___"three "quoted" "%NL%
___"four"%NL%
") DO (
@echo(%%~a
)
Salida
One<>&|
two 100%
three "quoted"
four
Intento explicar el código. La variable LF contiene un carácter de nueva línea, la variable NL contiene ^<LF><LF>^
.
Esto se puede usar con el porcentaje de expansión para colocar UN carácter de nueva línea y un símbolo de intercalación en el extremo de la línea.
Normalmente, un FOR / F divide un texto entre comillas en varios tokens, pero solo una vez.
Cuando inserto caracteres de nueva línea, el bucle FOR también se divide en varias líneas.
La cita en la primera y en la última línea es solo para crear la sintaxis correcta para el ciclo FOR.
Al frente de cualquier línea están _
ya que el primer carácter se escapará del cursor múltiple de la línea anterior, y si la cita es el primer carácter, pierde la capacidad de escape.
Los _
delims se usan, ya que los espacios o las comas causan problemas con XP (De lo contrario, el falso de XP-Bug intenta acceder a nombres de archivos basura).
El cursor en el extremo de la línea también es solo contra el XP-Bug.
El XP-Bug entra en vigencia cuando un texto entre comillas contiene caracteres sin comillas ,;=<space>
for /f "tokens=*" %%a in ("a","b","c") do echo %%a
Refiriéndose a la publicación de rojo en https://.com/a/15032476/3627676
Definitivamente, su solución es lo que estoy buscando por un tiempo (por supuesto, podría intentar implementar algo similar a esto, pero la pereza mueve el progreso :)). Una cosa que me gustaría agregar es una mejora menor al código original. Pensé que sería mejor si la redirección al archivo se escribiera al final de la línea. En este caso, la línea de inicio heredoc podría ser más estricta y su análisis más simple.
@echo off
set "hello=Hello world!"
set "lorem=Lorem ipsum dolor sit amet, consectetur adipiscing elit."
call :heredoc HTML & goto :HTML
<html>
<title>!hello!</title>
<body>
<p>Variables in heredoc should be surrounded by the exclamation mark (^!).</p>
<p>!lorem!</p>
<p>Exclamation mark (^!) and caret (^^) MUST be escaped with a caret (^^).</p>
</body>
</html>
:HTML
goto :EOF
:: https://.com/a/15032476/3627676
:heredoc LABEL
setlocal enabledelayedexpansion
set go=
for /f "delims=" %%A in ( ''
findstr /n "^" "%~f0"
'' ) do (
set "line=%%A"
set "line=!line:*:=!"
if defined go (
if /i "!line!" == "!go!" goto :EOF
echo:!line!
) else (
rem delims are ( ) > & | TAB , ; = SPACE
for /f "tokens=1-3 delims=()>&| ,;= " %%i in ( "!line!" ) do (
if /i "%%i %%j %%k" == "call :heredoc %1" (
set "go=%%k"
if not "!go:~0,1!" == ":" set "go=:!go!"
)
)
)
)
goto :EOF
¿Qué estoy sugiriendo por este código? Consideremos.
El código de Rojo es muy estricto
- no permite más de un carácter en blanco en la cadena entre
call
y:heredoc
-
call :heredoc
está pegado al borde de la línea (no se permiten espacios en blanco al comienzo de la línea) - la redirección al archivo está permitida en algún lugar dentro de la línea (no es muy útil) -
Cosas que estoy sugiriendo:
- menos estricto (más de un espacio en blanco como delimitadores)
- la redirección al archivo solo está permitida al final de la línea (se permiten y se necesitan corchetes redondeados)
- sin código adhesivo al borde de la línea
Actualización 1 : Mejoras para verificar y ejecutar el comienzo heredoc:
- El comando importante es solo
call :heredoc LABEL
ocall :heredoc :LABEL
. Entonces, después de imprimir el contenido heredoc, es posible saltar a otra etiqueta, al final del script o ejecutarexit /b
. - eliminado el comando innecesario e innecesario goto: next2
Actualización 2 :
- Delimitadores para interior
for
son(
)
>
&
|
TAB
;
=
SPACE
- El interruptor
/I
agregué aif
Actualización 3 :
En el siguiente enlace puede encontrar la versión completa de la secuencia de comandos independiente (la incrustación en sus secuencias de comandos está disponible) https://github.com/ildar-shaimordanov/tea-set/blob/master/bin/heredoc.bat
Sí, muy posible. ^ es el personaje de escape literal, simplemente ponlo antes de tu nueva línea. En este ejemplo, puse la nueva línea adicional también para que se imprima correctamente en el archivo:
@echo off
echo foo ^
this is ^
a multiline ^
echo > out.txt
Salida:
E:/>type out.txt
foo
this is
a multiline
echo
E:/>
@echo off
for /f "delims=:" %%a in (
''findstr -n "^___" %0'') do set "Line=%%a"
(for /f "skip=%Line% tokens=* eol=_" %%a in (
''type %0'') do echo(%%a) > out.html
:: out.html
pause
goto: EOF
___DATA___
<!Doctype html>
<html>
<head>
title></title>
</head>
<body>
<svg width="900" height="600">
<text x="230"
y="150"
font-size="100"
fill="blue"
stroke="gray"
stroke-width="1">
Hello World
</text>
</svg>
</body>
</html>
@echo off
cls
title Drop Bomb
echo/
echo/ creating...
:: Creating a batchfile from within a batchfile.
echo @echo off > boom.bat
echo cls >> boom.bat
echo color F0 >> boom.bat
echo echo/ >> boom.bat
echo echo --- B-O-O-M !!! --- >> boom.bat
echo echo/ >> boom.bat
echo pause >> boom.bat
echo exit >> boom.bat
:: Now lets set it off
start boom.bat
title That hurt my ears.
cls
echo/
echo - now look what you''ve done!
pause
C:/>more >file.txt
This is line 1 of file
This is line 2 of file
^C
C:/>type file.txt
This is line 1 of file
This is line 2 of file
** Se agregará una línea vacía al final, pero puedes resolverlo fácilmente, simplemente usando el método copy con:
C:/>copy con file.txt >nul
This is line 1 of file
This is line 2 of file^Z
C:/>type file.txt
This is line 1 of file
This is line 2 of file
Tenga cuidado donde escribe ^ C y ^ Z en cada caso.