Windows 批处理-如何在变量之间传递多行字符串值
问题是回声!出来显示除从指定的回显%data%之外的所有行!出来只显示第一行Windows 批处理-如何在变量之间传递多行字符串值,windows,batch-file,cmd,environment-variables,Windows,Batch File,Cmd,Environment Variables,问题是回声!出来显示除从指定的回显%data%之外的所有行!出来只显示第一行 @echo off call :f echo %data% :f setlocal EnableDelayedExpansion set out= set NL=^ for /f "delims=" %%i in ('dir /b') do ( if defined out set "out=!out!!NL!" set "out=!out!%%i" ) echo !out! set data=
@echo off
call :f
echo %data%
:f
setlocal EnableDelayedExpansion
set out=
set NL=^
for /f "delims=" %%i in ('dir /b') do (
if defined out set "out=!out!!NL!"
set "out=!out!%%i"
)
echo !out!
set data=!out!
exit /b 0
将值完全传递给我需要在endlocal之后自由使用的其他变量的正确方法是什么
感谢@aschipfl's的回答,澄清了如果不再次进入for循环是不可能做到的。实际上,我只想简化代码,而不必通过将其转换为子例程来多次编写for in循环。通过将子例程传递给子例程,我解决了这个问题。从中派生,您不能使用立即展开来回送多行字符串,因为第一个换行符之后的所有内容都将被忽略
要使脚本正常工作,您需要纠正两个问题:
在行endlocal&set data=%out%之前,必须将变量out中的每一新行替换为转义新行,即序列^plus new line plus new line,该序列与定义变量NL时使用的序列完全相同;
echo%data%在变量数据值中第一次出现新行时截断显示的字符串,因此您需要使用set data来显示变量的实际内容,或者更准确地说,显示名称以data开头的所有变量的实际内容;
以下代码中对这两项都进行了注释:
@回音
setlocal EnableDelayedExpansion
出发=
设置NL=^
对于'dir/b'do中的/F delims=eol=|%%i
如果已定义,则设置=!出来NL!
出发!出去!%%我
echo*原始变量内容:
动身
rem//用转义新行替换每一新行:
出发!输出:^%NL%%NL%=^^^%NL%%NL%^%NL%%NL%^%NL%!
echo*修改的变量内容:
动身
endlocal&设置数据=%out%
rem//不要使用'echo'显示变量的真实内容:
echo*返回的变量内容:
设置数据
echo*变量内容错误:
回显%数据%
退出/b0
虽然变量值现在已正确地传递到endlocal屏障上,但这种方法并不十分出色,因为它不允许您再次使用变量%data%,因为第一个换行符之后的所有内容都会被忽略,正如最初提到的,除非您在宿主cmd实例中启用了延迟扩展,这将允许使用!数据
另一个遗留问题是多行字符串中的特殊字符,如^、&、和|,可能会导致语法错误或其他意外问题。然而,这可以通过使用for元变量而不是普通环境变量来将变量值传递到endlocal屏障之外来避免,因为前者在特殊字符识别后展开,而后者在以下情况下展开:
@回音
setlocal EnableDelayedExpansion
出发=
设置NL=^
对于/F delims=%%i在“dir/b”do中
如果已定义,则设置=!出来NL!
出发!出去!%%我
回显原始变量内容:
动身
rem/*使用`for`元变量而不是普通环境变量
rem将变量值传递到“endlocal”屏障之外;
rem这里可以使用标准的'for'循环,因为不会有
rem通配符“?”和“*”在变量值中,因为它们已经
rem由'dir'解析`由于新行的原因,此处不能使用for/F`*/
为了%%j英寸!出来do endlocal&设置数据=%%~j
rem//不要使用'echo'显示变量的真实内容:
echo返回的变量内容:
设置数据
回显变量内容:
回显%数据%
退出/b0
但是,无法使用变量%data%的问题仍然存在
然而,为了能够在即时扩展中使用变量%data%,您可以简单地在变量中存储转义新行,而不是文本行,因为在扩展时,您将获得预期的文本新行:
@回音
setlocal EnableDelayedExpansion
出发=
设置NL=^
对于/F delims=%%i在“dir/b”do中
如果已定义,则设置=!出来NL!
出发!出去!%%我
回显原始变量内容:
动身
rem//用转义新行替换每一新行:
出发!输出:^%NL%%NL%=^^^%NL%%NL%^%NL%%NL%^%NL%!
echo修改的变量内容:
动身
rem/*使用`for`元变量而不是普通环境变量
rem将变量值传递到“endlocal”屏障之外;
rem这里可以使用标准的'for'循环,因为不会有
rem通配符“?”和“*”在变量值中,因为它们已经
rem由'dir'解析`由于新行的原因,此处不能使用for/F`*/
为了%%j英寸!出来do endlocal&设置数据=%%~j
rem//不要使用'echo'显示变量的真实内容:
回显实际变量内容:
设置数据
回显解析的变量内容:
回显%数据%
退出/b0
但请注意,只有当%data%未出现在带引号的字符串中时,此操作才会起作用。通过禁用延迟扩展,可以完全避免此情况,尽管转义很复杂&out的内容将无法正确处理。看…我真的不知道你为什么
e创建了这个问题,但没有明确告诉读者您正在尝试创建一个变量,以保存Dir命令输出的全部内容。我的问题是,使用EndLocal的原因是什么?它所做的一切就是取消定义名为NL和out的变量,您可以简单地使用Set NL=和Set out=,或者在For循环之后立即对%%G In NL out Do Set%%G=执行此操作@对不起。我认为简化这个问题会更清楚。我已经编辑好了。谢谢你的回答。所以基本上我仍然需要使用for-in循环来完全复制这个值。很清楚