标题: [文本处理] 【已解决】@的复杂用法与疑惑 [打印本页]
作者: 踏沙行 时间: 2018-7-5 10:18 标题: 【已解决】@的复杂用法与疑惑
本帖最后由 踏沙行 于 2018-7-20 12:32 编辑
@的用法,按常规说法是:本行命令不显示(在控制台)
但在下面的实例中,这一用法却非常困惑,请大神指点
例:在test02.txt中,保存以下内容:- aldskfj zsdlf dblkj
- 不灭星辰诀 巅峰黑客
- xxdl DDty 123ft
- 重生之修真霸道 张天扬 至尊无赖
复制代码
1、完整显示test02.txt的内容,代码如下:- 1.方法一:
- @echo off
- for /f "delims=" %%i in (test02.txt) do echo.%%i
- pause
-
- 1.方法二:
- @echo off
- for /f "delims=" %%i in (test02.txt) do @echo.%%i
- pause
复制代码
【问】方法二使用了@echo %%i,为什么还显示结果呢?
2、对test02.txt内容排序- 2.方法一:echo前加@
- @echo off
- (for /f "delims=" %%i in (test02.txt) do @echo.%%i) |sort
- pause
-
- ====结果=========
- aldskfj zsdlf dblkj
- xxdl DDty 123ft
- 不灭星辰诀 巅峰黑客
- 重生之修真霸道 张天扬 至尊无赖
复制代码
- 2.方法二:echo前不加@
- @echo off
- (for /f "delims=" %%i in (test02.txt) do echo.%%i) |sort
- pause
-
- ========结果========
-
-
-
-
-
- aldskfj zsdlf dblkj
- I:\>echo.aldskfj zsdlf dblkj
- I:\>echo.xxdl DDty 123ft
- I:\>echo.不灭星辰诀 巅峰黑客
- I:\>echo.重生之修真霸道 张天扬 至尊无赖
- xxdl DDty 123ft
- 不灭星辰诀 巅峰黑客
- 重生之修真霸道 张天扬 至尊无赖
复制代码
【区别】方法二未在echo前加@,不仅显示了多个命令行,而且开始还有好多空行。
【疑惑】for 使用的是逐行输出,所以输出结果会出现4行命令,但是:
(1)为什么开头还有好多空行?
(2)为什么4行命令会出现在输出内容的中间部分,而不是一行命令,一行输出结果呢?
3、对test02.txt的所有字段排序(即以空格分开的字段排序)- 3.方法一,do后面加括号
- @echo off
- (for /f "delims=" %%i in (test02.txt) do (@for %%a in (%%i) do @echo.%%a)) |sort
- pause
-
- =====结果========
-
-
-
-
- 123ft
- aldskfj
- dblkj
- DDty
- I:\>()
- I:\>()
- I:\>()
- I:\>()
- xxdl
- zsdlf
- 不灭星辰诀
- 巅峰黑客
- 张天扬
- 至尊无赖
- 重生之修真霸道
复制代码
- 3.方法二:do后面不加括号
- @echo off
- (for /f "delims=" %%i in (test02.txt) do @for %%a in (%%i) do @echo.%%a) |sort
- pause
-
- =======结果正确======
- 123ft
- aldskfj
- dblkj
- DDty
- xxdl
- zsdlf
- 不灭星辰诀
- 巅峰黑客
- 张天扬
- 至尊无赖
- 重生之修真霸道
复制代码
- 3.方法三:使用括号,但在括号前加@
- @echo off
- (for /f "delims=" %%i in (test02.txt) do @(for %%a in (%%i) do @echo.%%a)) |sort
- pause
-
- ===结果同上:正确=====
复制代码
【疑惑】
1、3.方法二中,在in后面有两个do,又加使用括号,cmd为什么还能正确解析呢?
2、3.方法一中,为什么仅仅在第一个do前面加了括号,就多出来好多空行和命令行呢?
3、@的作用,不应该是作用本行,而应该是作用本命令、本括号吗?
作者: 狄钦dQ 时间: 2018-7-5 23:59
本帖最后由 狄钦dQ 于 2018-7-6 00:29 编辑
对于1:楼主怕是误解@的意思,作用是关闭命令自身回显。
先科普下echo命令和@用法:http://www.bathome.net/thread-13860-1-1.html
for语句内 @echo 是没有意义的。批处理开头@echo off 相当于在每一个命令前补上一个@,从而实现关闭了所有命令的回显。
括号()+管道符|的组合:- @echo off
- ( for /l %%i in (1,1,5) do echo bathome ) | find "a"
- echo ============================
- ( for /l %%i in (1,1,5) do echo bathome ) | find "r"
- echo ============================
- ( for /l %%i in (1,1,5) do echo bathome ) | find "z"
- pause
复制代码
以上代码请细心品味,再删去@echo off重新品味。
解读:第2个和第3个for语句应该结果相同,然而第2个却能看到echo的输出结果,此处应该涉及到批处理的一堵高墙,预处理机制。(能力有限,不做深入分析)
括号将for语句整个包裹,而管道符| 连接着find命令,这是一句完整的语句。该复合语句的含义是:进行5次循环,同时执行echo输出,成功后,将结果传给find命令执行,再得到最后的匹配结果。- D:\Users\Desktop>(for /L %i in (1 1 5) do echo bathome ) | find "a"
- D:\Users\Desktop>echo bathome
- bathome
- D:\Users\Desktop>echo bathome
- bathome
- D:\Users\Desktop>echo bathome
- bathome
- D:\Users\Desktop>echo bathome
- bathome
- D:\Users\Desktop>echo bathome
- bathome
复制代码
可见以上过程产生了两次结果。上例中第2和3条for语句得到的结果不同,虽然是在find命令得到echo的输出结果才显示匹配结果。- @echo off
- setlocal enabledelayedexpansion
- for /l %%i in (1,1,5) do echo bathome | find "a"
- echo ============================
- for /l %%i in (1,1,5) do echo bathome | find "r"
- echo ============================
- for /l %%i in (1,1,5) do echo bathome
- pause
复制代码
同样删去@echo off再品味。
几个回答:
1. 为何多个很多空格?
echo输出末尾带换行符。sort命令把每次echo的换行符也做了排序,多少次echo就有多少次换行。这也涉及到"括号的正确使用"。
2. 括号()和@关闭回显的关系?
@ 是作用于单个命令,严格来说不是语句,更不是一行。对于复合语句,@只关闭后面的第一条命令的回显,也无法关闭括号内的所有命令回显,括号内之后的命令还是会显示。
楼主的例2方法一之所以能显示echo语句,正是由于整个for语句被括号包裹,而echo off只是在括号外加了一个@,但这只是关闭一个命令回显,其后仍然会显示。
以上仅代表本人看法,未完待续,等待大佬做权威解答。
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |