标题: 用一行批处理实现标签跳转 [打印本页]
作者: cjiabing 时间: 2011-8-16 23:44 标题: 用一行批处理实现标签跳转
将含有标签跳转命令的多行代码转换成一行。如:-
- if exist c:\123.txt (goto a) else (goto b)
- exit
- :a
- echo yes
- pause&exit
- :b
- echo no
- pause&exit
复制代码
转换结果示例:- if exist c:\123.txt (goto a) else (goto b)&exit&:a&echo yes&pause&exit&:b&echo no&pause&exit
复制代码
直接用 & 将每一行连接起来了,但无法执行或结果没有达到目标要求。
有何难度?
这个问题看似无法完成,主要是因为在连接标签名时,标签会失效。特别是许多命令,包括标签自身,都是通过行来定义执行的,离开行后命令会失效。
但,也正是不可能实现的问题才放出来挑战各位的思想和技术,希望有人能够实现。
这样做有什么用?
第一、在CMD窗口实现批处理脚本的标签功能。在CMD窗口是无法使用标签的,除非你在CMD窗口调用其他批处理脚本文件,虽然CMD帮助里有“goto/?”。 “cmd /c”命令有个弊端,就是它只支持一行命令参数,有多行就会出错。假如能将将许多命令压缩到一行中,包括标签跳转等,将极大的扩展“cmd /c”命令的使用,这样,大家可以使用cmd命令来取代临时文件。
第二、扩展变量型函数。同样,在变量型函数中,命令同样只能使用一行,不能多行,不能标签,限制了变量函数的应用。假如变量函数能包容更多的批处理脚本命令,将使得变量函数使用更加广泛。
批处理函数的高效另类应用(免call的哦!):http://www.bathome.net/viewthread.php?tid=5861
一些标签实验:
1、如何在标签名前面放置命令?
2、如何执行标签后的命令?-
- @echo off
- goto b
- pause
- exit
- (:b&echo I'am here)
- echo U lose
- pause&exit
- :b
- echo U wrong
- pause&exit
-
- 有效的标签:
- (:b&echo I'am here)
- (:b&echo I'am here
- :b:aaaaaaaaaaaecho I'am here
- ;;;;;;;;;;:b&echo I'am here
- ;;;;;;;;;:;;;;;b&echo I'am here
- ;;;=;;,;;; ;:;;=;,;;b&echo I'am here
- ;;;=;;,;;; ;:;;=;,;;b fsdfweer323,.^echo I'am here
-
- 无效(无法执行标签后的命令或者标签无效):
- &(:b&echo I'am here)
- [:b]
- ...:b
- :b (%I'am here%)
- :b %echo I'am here%
- :b echo I'am here^&echo U lose
- ;;;=;;,;;; ;:;;=;,;;b echo I'am here&echo U lose&pause&exit
复制代码
标签的一些属性
1、独立一行;
2、标签前可以添加一些无意义的符号,如“; = :”,而且可以同时使用多个且不影响标签名的有效性,还可将标签的冒号和标签名分开;
3、标签名后可以使用空格、冒号、&、|等少数几个符号分隔,使用其它字符示为标签名的有效组成部分,改变标签;
4、标签名后的命令无法执行,即使使用&也无济于事,因此,可以直接在标签名后写注释。
作者: raymai97 时间: 2011-8-17 00:22
感觉是没法子的~ 不过俺有一个想法。如果情况可以的话,就把- if exist c:\123.txt (goto a) else (goto b)
- exit
- :a
- echo yes
- pause&exit
- :b
- echo no
- pause&exit
复制代码
变成- if exist c:\123.txt (echo yes) else (echo no)
- pause
- exit
复制代码
但问题是,通常都不只是echo这样简单……
“使用cmd命令来取代临时文件”?
俺不是很明白,可不可以给些例子,来证明cmd /c可以取代临时文件?
作者: cjiabing 时间: 2011-8-17 16:13
回复 2# raymai97
你那个是投机取巧了,无法适应更多情况,至于取代临时文件暂时没有更好的想法。
作者: cjiabing 时间: 2011-8-17 16:44
具体的应用说明
举个简单的例子:
使用AT命令定时执行一串命令,而不必一个BAT
- at 16:40 cmd /q /c "%GetPath0%BmpProgram\read.vbs" !Input1! !Input1!&at 16:40 cmd /q /c !Input1!
复制代码
使用一个cmd命令,而不必使用一个bat执行reg:
- reg add HKCR\Audio.%%a\shell\PlayList\command /t REG_SZ e /f /d "cmd /q /c echo;"%%1" %%*>>\"!GetPath0!PlayList\PL.txt\"
复制代码
使得start操作更有搞头:
- start /b "" cmd /c "(for /l %%a in (%daojs%,-1,0) do @title %%a&ping /n 2 127.0.1>nul&if exist "%temp%\$0.tmp" exit)&&(cd.>"%temp%\$1.tmp")"
复制代码
在以上命令中虽然没有使用到标签跳转,到假如有标签跳转的话,我可以实现更多功能
我在实践中用得比较多cmd和start,所以希望它们能够产生一个类似于bat的效果,发挥更大的作用。
作者: raymai97 时间: 2011-8-17 17:40
回复 4# cjiabing
这样的话,不如使用类似“start /b "%~0" ray”来start回自己的批处理的一部分,这样就不用担心多行的问题了
比如:- @echo off
- if "%1"=="ray" goto ray
- start /b "" "%~0" ray
- exit
- :ray
- mode con cols=20 lines=7
- echo.
- echo 多行不是问题了。
- echo.
- echo 哈哈。
- pause>nul
- exit
复制代码
作者: plp626 时间: 2011-8-17 19:49
本帖最后由 plp626 于 2011-8-17 19:50 编辑
批处理源文件的行是以换行符标识的;
硬要一行实现跳转那就强行给标签后面加一个换行符
(但这和回车换行符的道理是一样的,仅仅是视觉上在一行而已):- @echo off
- :a【换行符】echo %time%&goto:a
复制代码
- :: 保存为create.bat 桌面双击之,就可生成测试代码test.bat
- @echo off&setlocal enabledelayedexpansion
- set nl=^
-
-
- (echo @echo off
- echo :a!nl!echo %%time%%^&goto:a
- )>test.bat
- pause
复制代码
作者: cjiabing 时间: 2011-8-17 21:20
回复 5# raymai97
确实可以,都忘记START自身了,和CALL一样吧。
虽然这种方法仍然是批处理脚本文件下使用的,总比临时文件之类的好多了,有很大的用途,基本上足够实践使用了。谢谢!~
假如放到CMD窗口就不好如此了,基于以上,直接在CMD窗口使用标签有点苛刻了,当挑战好了。
修改了一下,多运行几次你会有所发现。
- @echo off
- if "%1"=="ray" goto ray
- start /b "" cmd /c "%~0" ray
- echo,
- call :a
- echo [4]
- exit
-
- :a
- echo [2]
- dir /b
- call :b
- goto :Eof
-
- :ray
- set var=0
- :loop
- set /a var+=1
- echo.
- echo [1]多行不是问题了。共循环 %var% 次。
- echo.
- pause>nul
- if %var% lss 5 goto loop
- exit /b
-
- :b
- echo.
- echo [3]I'am here
- echo.
- goto :eof
复制代码
该代码多运行几次偶尔会出现乱码。
作者: cjiabing 时间: 2011-8-17 21:32
回复 6# plp626
非常好,我进行了测试,初步达到目标!~继续测试看看,添加变量,添加IF,添加新的标签。
作者: cjiabing 时间: 2011-8-17 22:02
回复 6# plp626
哈哈,改造成功,不过费了点劲。将以下代码改造成后面的一行代码
原代码:
- set nb=0
- :a
- set /a nb+=1
- echo %%time%%
- if %nb% lss 300 (goto b) else (goto a)
- exit
- :b
- echo OK***************
- for /l %%a in (1,1,10) do echo %random%
- pause
复制代码
改造后的新代码:一行搞掂!~
-
- :: 保存为create.bat 桌面双击之,就可生成测试代码test.bat
- :: 标签名后添加一个!nl!,一个!nl!表示一个回车。
- :: 在编辑代码中,百分号要加倍;连接符&需加转移符,变成 ^&。
- @echo off&setlocal enabledelayedexpansion
- set nl=^
- >test.bat (
- echo @echo off
- echo set nb=0!nl!:a!nl!set /a nb+=1^&echo %%time%%^&^(if %%nb%% lss 300 ^(goto a^) else ^(goto b^)^)^&pause^&exit!nl!:b!nl!echo OK***************^&(for /l ^%%^%%a in ^(1,1,10^) ^do echo %%random%%^)^&^pause
- )
- call test.bat
- echo over
- pause
-
复制代码
作者: CrLf 时间: 2011-8-17 22:52
回复 9# cjiabing
只是看起来是一行,其实 cmd 从文件读入命令时仍然是以换行符分行的,所以若想在 cmd /c 中直接使用换行符作为参数的一部分,那应该是死胡同
作者: cjiabing 时间: 2011-8-17 23:15
本帖最后由 cjiabing 于 2011-8-17 23:18 编辑
回复 10# CrLf
看来似乎如此,弄了半天都不得:
-
-
- @echo on&setlocal enabledelayedexpansion
- set nl=^
-
- cmd /v:on /c (:a!nl!&echo !time!&echo !time!&goto:a)
- echo over
- pause
复制代码
找不到标签!~
不过有个问题,cmd与bat在流程构造上如此不同,那么,bat是如何使用cmd解释的?
作者: raymai97 时间: 2011-8-17 23:47
回复 raymai97
确实可以,都忘记START自身了,和CALL一样吧。
虽然这种方法仍然是批处理脚本文件下使 ...
cjiabing 发表于 2011-8-17 21:20
我运行了多次,都没有乱码啊~ 嗯,建议楼主去看看那些以前的帖子,会得到启发哦~ 好像这个start也是看那个“随风”的批处理才想到的~
作者: CrLf 时间: 2011-8-17 23:48
bat 中的标签...好像寒夜说过是碰到跳转才从文本读标签,不知道有没记错
二者的区别更主要体现在对 % 和 ! 的处理上
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |