有没有办法以类似于 unix shell 中的 heredoc 的方式批量指定多行字符串。类似于:
cat <<EOF > out.txt
bla
bla
..
EOF
这个想法是从模板文件创建一个自定义文件..
有没有办法以类似于 unix shell 中的 heredoc 的方式批量指定多行字符串。类似于:
cat <<EOF > out.txt
bla
bla
..
EOF
这个想法是从模板文件创建一个自定义文件..
据我所知不是。
我所知道的最接近的是
> out.txt (
@echo.bla
@echo.bla
...
)
(@
防止命令外壳本身打印它正在运行的命令,并echo.
允许您以空格开始一行。)
这是另一种方法。
@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
示例输出:
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. :)
是的,很有可能。^ 是文字转义字符,只需将其放在换行符之前。在此示例中,我还添加了额外的换行符,以便在文件中正确打印:
@echo off
echo foo ^
this is ^
a multiline ^
echo > out.txt
输出:
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>
在 DosTips 上,siberia- man以(goto) 2>nul
. Aacini 和 jeb 然后记录了一些关于奇怪行为的额外有趣发现。它的行为基本上类似于EXIT /B
,除了它允许 CALLed 例程中的串联命令在父调用者的上下文中执行。
这是一个简短的脚本,演示了大部分要点:
@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
- 输出 -
var=Parent Value
How did I get here!!!!
这种惊人的行为使我能够编写一个优雅的here doc批处理模拟,其中包含许多unix可用的选项。我将 PrintHere.bat 实现为一个独立的实用程序,该实用程序应放置在 PATH 中列出的文件夹中。然后任何批处理脚本都可以轻松调用该实用程序来获取此处的文档功能。
这是使用的一般语法:
call PrintHere :Label
Here doc text goes here
:Label
这怎么可能实现?...我的 PrintHere 实用程序(GOTO) 2>nul
两次使用了这个技巧。
我第一次使用(GOTO) 2>nul
返回给调用者,这样我就可以获得调用脚本的完整路径,以便 PrintHere 知道要从哪个文件读取。然后我第二次调用 PrintHere!
我第二次使用(GOTO) 2>nul
返回给调用者并转到终止标签,以便不执行此处的文档文本。
注意 - 下面的脚本在标签的定义中包含一个制表符 (0x09),位于标签的正下方:start
。某些浏览器可能难以显示和复制选项卡。作为替代方案,您可以从我的 dropbox 下载 PrintHere.bat.txt,然后简单地将其重命名为 PrintHere.bat。
我最初在DosTips 上发布了 PrintHere.bat,您可以在其中跟踪未来的发展。
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
完整的文档嵌入在脚本中。下面是一些使用演示:
逐字输出
@echo off
call PrintHere :verbatim
Hello !username!^!
It is !time! on !date!.
:verbatim
- 输出 -
Hello !username!^!
It is !time! on !date!.
扩展变量(延迟扩展不需要启用)
@echo off
call PrintHere /E :Expand
Hello !username!^!
It is !time! on !date!.
:Expand
- 输出 -
Hello Dave!
It is 20:08:15.35 on Fri 07/03/2015.
展开变量并修剪前导空格
@echo off
call PrintHere /E /- " " :Expand
Hello !username!^!
It is !time! on !date!.
:Expand
- 输出 -
Hello Dave!
It is 20:10:46.09 on Fri 07/03/2015.
输出可以重定向到文件
@echo off
call PrintHere :label >helloWorld.bat
@echo Hello world!
:label
输出不能作为输入重定向,但可以通过管道传输!不幸的是,语法并不那么优雅,因为管道的两端都在新的 CMD.EXE 进程中执行,因此(GOTO) 2>nul
返回到子 cmd 进程,而不是主脚本。
@echo off
call PrintHere :label "%~f0" | findstr "^" & goto :label
Text content goes here
:label
使用带有参数的宏允许以更简单的方式编写“heredoc”:
@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
@jeb
setlocal EnableDelayedExpansion
set LF=^
REM Two empty lines are required
另一种变体:
@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
参考 rojo 在https://stackoverflow.com/a/15032476/3627676上的帖子
毫无疑问,他的解决方案是我一直在寻求的(当然,我可以尝试实现类似的东西,但懒惰会推动进步:))。我想补充的一件事是对原始代码的小改进。我认为如果重定向到文件写在行尾会更好。在这种情况下,heredoc 起始行可能更严格,分析更简单。
@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://stackoverflow.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
我对这段代码有什么建议?让我们考虑一下。
Rojo 的代码非常严格:
call
和之间的字符串中不允许有多个空格字符:heredoc
call :heredoc
粘在行的边缘(行首不允许有任何空格)我建议的事情:
更新 1:改进检查和执行 heredoc 开始:
call :heredoc LABEL
or call :heredoc :LABEL
。因此,在打印 heredoc 内容后,可以跳转到另一个标签、脚本结尾或运行exit /b
。更新 2:
for
是(
)
>
&
|
TAB
,
;
=
SPACE
/I
添加到if
更新 3:
通过以下链接,您可以找到完整版本的独立脚本(可以嵌入到您的脚本中)https://github.com/ildar-shaimordanov/cmd.scripts/blob/master/heredoc.bat
您可以使用 FOR /F 循环创建带引号的文本块,因此您不需要转义特殊字符,例如<>|&
只%
需要转义。
这有时像创建 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
)
输出
One<>&|
two 100%
three "quoted"
four
我尝试解释代码。LF 变量包含一个换行符,NL 变量包含^<LF><LF>^
.
这可以与百分比扩展一起使用,以在行尾放置一个换行符和一个插入符号。
通常一个 FOR /F 将引用的文本分成多个标记,但只有一次。
当我插入换行符时,FOR 循环也分成多行。
第一行和最后一行的引号仅用于为 FOR 循环创建正确的语法。
在任何行的前面都是_
因为第一个字符将从前一行的多行插入符号中转义,如果引号是第一个字符,它将失去转义能力。
使用_
分隔符,因为空格或逗号会导致 XP 出现问题(否则 XP-Bug 虚假会尝试访问垃圾文件名)。
行尾的插入符号也仅针对 XP-Bug。
,;=<space>
当引用的文本包含未引用的字符时,XP-Bug 生效
for /f "tokens=*" %%a in ("a","b","c") do echo %%a
@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
这是 ehemient 出色解决方案的一种变体。这允许您将多行管道传输到另一个程序,而无需实际创建文本文件并将其输入重定向到您的程序:
(@echo.bla
@echo.bla
) | yourprog.exe
对于一个快速有效的示例,您可以替换yourprog.exe
为more
:
(@echo.bla
@echo.bla
) | more
输出:
bla
bla
扩展ephemient post,我觉得最好,下面会做一个管道:
(
@echo.line1
@echo.line2 %time% %os%
@echo.
@echo.line4
) | more
在 ehemient 的帖子中,他在开头重定向,这是一种不错的风格,但您也可以在末尾重定向:
(
@echo.line1
@echo.line2 %time% %os%
@echo.
@echo.line4
) >C:\Temp\test.txt
请注意“@echo”。永远不会包含在输出和“@echo”中。本身给出一个空行。
在 Microsoft NMake makefile中,可以使用真正的UNIX heredocs,因为线程所有者要求它们。例如,这是创建文件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
其中<<扩展为 NMake 在执行规则时动态创建的临时文件名。也就是说,当Deploy.sed不存在时。好消息是 NMake 变量也被扩展了(这里是变量NAME和VERSION)。将此保存为makefile。在makefile目录中打开一个 DOS 框并使用:
> nmake Deploy.sed
创建文件,并且:
> nmake clean
删除它。NMake 是所有 Visual Studio C++ 版本的一部分,包括 Express 版本。
在紧要关头,我使用以下方法(不会减少任何其他方法,这只是个人喜好):
我通过一组字符串使用 for 循环:
for %%l in (
"This is my"
"multi-line here document"
"that this batch file"
"will print!"
) do echo.%%~l >> here.txt
这是我目前正在处理的脚本中的另一个实际示例:
:intc_version:
for %%l in (
"File : %_SCRIPT_NAME%"
"Version : %_VERSION%"
"Company : %_COMPANY%"
"License : %_LICENSE%"
"Description : %_DESCRIPTION%"
""
) do echo.%%~l
exit /B 0
OP 想要的是一些非常具体的东西(使用输出创建一个文本文件),并且接受的答案完美地做到了这一点,但是提出的解决方案在该特定上下文之外无法正常工作。例如,如果我想将多行输入传递给命令,我就不能使用( echo )
语法。这就是最终为我工作的东西。
给定一个名为“echolines.pl”的 perl 脚本,包含以下内容(模拟“真实”程序):
use strict;
use warnings;
while (<>) {
chomp;
print qq(<$_>\n);
}
和一个名为“testme.bat”的批处理文件,其中包含:
@echo off
set FOO=foo
set BAR=bar
set BAZ=baz
echo %FOO%^
&echo %BAR%^
&echo %BAZ%|perl echolines.pl
运行它会产生预期的输出:
C:\>testme
<foo>
<bar>
<baz>
必须注意空格,以确保它在任何地方都没有杂散空间正常工作。具体来说:每个行尾应该是一个插入符号 (^) 后跟一个换行符,后续行必须立即以与号 (&) 开头,最后一行必须在要发送的最后一项之后立即开始管道。不这样做会导致参数丢失或参数前后有多余的空格。
试试这个代码。(底部的 JScript 代码将“out.html”写入磁盘)
@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();
在 .bat 文件中:
(
@echo.bla
@echo.bla
@echo...
) > out.txt
然后
type out.txt
生产
bla
bla
..
有点混乱,必须放在@echo.
每一行的开头,但它基本上可以满足您的需求:将依赖文件滚动到脚本文件本身的能力。
还有很多其他解决方案,但所有这些都需要添加更多代码才能以更简洁的方式完成基本相同的事情。在一种情况下,甚至需要一个完整的其他 .bat 文件作为新的依赖项!
B.Reynolds 的道具,我的回答受到了他们的启发。
这更容易,并且非常类似于 cat << EOF > out.txt:
C:\>copy con out.txt
这是我的第一行文字。
这是我的最后一行文字。
^Z
已复制 1 个文件。
输出如下所示:
C:\>type out.txt
这是我的第一行文本。
这是我的最后一行文字。
(复制 con + out.txt,输入您的输入,然后按 Ctrl-Z 并复制文件)
COPY CON 表示“从控制台复制”(接受用户输入)
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
**它会在最后添加一个空行,但你可以很容易地解决这个问题,只需使用 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
请注意在每种情况下键入 ^C 和 ^Z 的位置。