Board logo

标题: [文本处理] 批处理文件中变量值前加上%%用作for的参数? [打印本页]

作者: lyc309    时间: 2011-12-10 11:56     标题: 批处理文件中变量值前加上%%用作for的参数?

  1. :import
  2. echo 你要处理的博客地址:
  3. echo 1. 新浪 2. 163 3. soho
  4. set /p var=请输入一数字:
  5. if "%var%"=="1" (goto work) else (
  6. if "%var%"=="2" (goto work) else (
  7.   if "%var%"=="3" (goto work) else (
  8.    if "%var%"=="4" (goto work) else (
  9.     if "%var%"=="5" (goto work) else (
  10.      if "%var%"=="6" (goto work) else goto fail
  11.     )
  12. )
  13. :fail
  14. echo 请重新输入不大于5的数
  15. goto import
  16. :work
  17. for /f "tokens=1 delims=," %%1 in ("新浪,163,soho") do set/p  Url=%%var%%
  18. echo %Url%
  19. goto import
复制代码
上面是我的代码
想问两个问题第一个:如果不按照单行写的话,如下面
  1. if "%var%"=="1" goto work
  2. if "%var%"=="2" goto work
  3. if "%var%"=="3" goto work
  4. if "%var%"=="4" goto work
  5. if "%var%"=="5" goto work
  6. if "%var%"=="6" goto work
复制代码
把代码改成比如我上面代码的,或者像下面的代码。输入数字后窗口直接退出,
  1. if "%var%"gep "7" goto work
复制代码
这是为什么呢!
第二个问题
  1. Url=%%%var
复制代码
想在用户输入2或者某数的时候,url=%%2(或者其他数)
让for语句能顺利读取括号内相应的字符
作者: yyykkkyyyy    时间: 2011-12-10 12:37

本帖最后由 yyykkkyyyy 于 2011-12-10 12:39 编辑

需要加强各命令基本语法练习
1 批处理一般情况都是顺序执行的,对if... 处理形式为goto ... 的,可以不用else... 因为跳开后不会顺序执行了,正如你上面那6行代码的那样是没有什么问题的(那个gep是错的)虽然代码用别的命令还可简化。
2 本来按代码用途没必要用for,不过标题的说的功能是可以实现的
  1. for /f "tokens=1-6 delims=," %%1 in ("新浪,163,soho") do set Url=%%%var%
  2. if defined url echo 选择的是 %url%
复制代码

作者: lyc309    时间: 2011-12-10 12:49

需要加强各命令基本语法练习
1 批处理一般情况都是顺序执行的,对if... 处理形式为goto ... 的,可以不用el ...
yyykkkyyyy 发表于 2011-12-10 12:37



    谢谢,正在学基础呢!
但是用这个时候
  1. if "%var%"=="1" (goto work) else (
  2. if "%var%"=="2" (goto work) else (
  3.   if "%var%"=="3" (goto work) else (
  4.    if "%var%"=="4" (goto work) else (
  5.     if "%var%"=="5" (goto work) else (
  6.      if "%var%"=="6" (goto work) else goto fail
  7.     )
  8. )
复制代码
输入数字的时候直接退出,不知道怎么回事?你可以测试下。dos有没有直接判断大于几的退出简单写法
本来按代码用途没必要用for,不过标题的说的功能是可以实现的

可以请问下可以用什么呢?
作者: yyykkkyyyy    时间: 2011-12-10 13:27

回复 3# lyc309


    这个不用试,不要说逻辑上如何,括号都没配套成对,当然不对
说可以不用for 是因为每项总是单列出来的,谁都会如 if "%var%"=="1" set url=新浪
一般接收键盘输入最好防输错,可以类似如下判断(至于大于多少之类的,看set/? 退出命令可用goto ...也可用exit):
  1. :import
  2. echo 你要处理的博客地址:
  3. echo 1. 新浪 2. 163  3. soho
  4. set /p var=请输入一数字:
  5. echo %var%|findstr/x "[1-3]">nul||(
  6.   echo 选择有误
  7.   goto :import)
复制代码

作者: CrLf    时间: 2011-12-10 15:19

回复 4# yyykkkyyyy


其实如果是纯数字的话,用 set /a 来判断更绿色无污染,不过会自动将用户输入的八进制、十六进制数转为十进制。非必要情况尽量避免使用外部命令,对代码效率和容错性的提升是有可观效果的。
  1. set /a "test/=!!(var/4)+!(var/1)" 2>nul&&echo 错误||echo 正确
复制代码
或者用 for 亦可:
  1. setlocal enabledelayedexpansion
  2. for /f "delims=123" %%a in ("!var!") do set error=1
  3. if defined error (echo 错误) else echo 正确
复制代码
如果输入的不是单个字符,那也有简化的办法,不过不兼容含双引号和感叹号的 %var%
  1. set str="123"abc"QWE"@#$"
  2. setlocal enabledelayedexpansion
  3. if "!str:"%var:"=%"=!"=="!str!" set error=0
复制代码
当然也可以用笨办法...
  1. setlocal enabledelayedexpansion
  2. for %%a in (123 abc QWE @#$) do if %%a==!var! echo 正确&set error=1
  3. if not defined error echo 错误
复制代码

作者: 冷玉公子    时间: 2011-12-10 17:25

  1. :import
  2. echo 你要处理的博客地址:
  3. echo 1. 新浪 2. 163 3. soho
  4. set /p var=请输入一数字:
  5. if "%var%"=="1" goto work
  6. if "%var%"=="2" goto work
  7. if "%var%"=="3" goto work
  8. if "%var%"=="4" goto work
  9. if "%var%"=="5" goto work
  10. if "%var%"=="6" goto work else goto fail
  11. :fail           
  12. echo 请重新输入不大于5的数
  13. cls
  14. goto import
  15. :work
  16. for /f "tokens=1 delims=," %%1 in ("新浪,163,soho") do set Url=%var%
  17. echo %Url% & Pause
  18. cls
  19. goto import
复制代码

作者: yyykkkyyyy    时间: 2011-12-10 18:09

回复 5# CrLf


     非常感谢版主细致指导, 你说得很有道理, 但是我还是坚持我这错误观点,理由是:
用在对set/p 判断用户输入选项本身就是一个停顿, 完全可以忽略代码运行效果的差别, 显然 echo | findstr 的形式 具有最简捷的代码,如果是需要多次循环运行中的代码,哪怕是稍有一点效率上的差别都应该是效率优先
   呵呵,我和版主追求的目标存在差距呀,当然是我水平差多了, 我是到不了批处理较高境界的, 多数情况批处理优势就是系统自带,灵活方便,真个需要讲究算法和效率的不如用某编程语言了
作者: CrLf    时间: 2011-12-10 19:07

回复 7# yyykkkyyyy


    可能真的是追求不同吧,DOS联盟的代码和批处理之家的代码在间接性与效率上便有此分歧,也难说谁对谁错,只有合适与不合适...比如联盟的代码偏爱用 goto 和 call,而批处理之家则是用 for 和变量延迟的更多,联盟代码追求简短和可读性(比如将一个特效细分为几个模块来反复调用),这里的代码相对追求高效和通用性(比如频繁的 setlocal 和 endlocal 保持对特殊字符的兼容)。
    嗯,说到外部命令,就顺便说一说我的个人理解吧,当然可能比较主观,仅仅是个人看法:
  1. 最明显的缺点是启动效率低,这是公认的,创建进程是一个很复杂的过程,所以频繁启动新进程会降低效率
  2. 优点在于启动后的执行效率远高于脚本,这是脚本与程序之间质的差距,同样不可否认,两者的效率以千倍万倍计
  3. 灵活性很难和内部命令的组合媲美,可以预计,一个罗纳尔多再怎么也踢不过整编国足,单个内部命令是很弱小的(哪怕是 for),但是有秩序的团结是一股可怕的力量
  4. 较容易受环境影响,比如系统被阉割、path 变量被改变、优先级高的目录下有同名可执行文件、杀软拦截等都可能是致命的
  5. 一般不需要对文件进行过于复杂的语法解释,因此基本免疫脚本中让人头疼的特殊字符
  6. 由于微软不开源,很难了解它们的工作流程,所以有时会产生让人费解的错误
复制代码
综上所述,我个人认为,外部命令更适合在一个比较稳定的环境中用于处理大量的输入的少量的调用,在这种情况下能把程序的优势发挥到极致,而弥补了脚本运行效率低的缺陷,当外部命令所提高的执行效率超过启动它付出的代价时,那它当然是更好的选择。本人就十分偏爱 findstr,但是实战中尽量用它来对付千军万马,而避免出现大材小用的情况。
    说了这么多,只是一家之言,有感于外部命令的话题而发的一些长久以来的看法,并非说孰好孰坏,一题多解,这种宽泛的自由度正是批处理的魅力之一。
    在我学批的时候,受寒夜和随风两位版主的影响甚重,故以效率至上为信条,其次才是并列的兼容性和简洁程度,一切代码均围绕这一点来考虑,所以可能有时显得苛求效率了呵呵。
作者: jellyhk    时间: 2011-12-10 21:58

  1. if "%var%"gep "7" goto work
复制代码
搞什么东东?你是想判断小于7吧你搞个gep干什么。gep是大于等于!兄弟!换了!
作者: lyc309    时间: 2011-12-10 23:53

搞什么东东?你是想判断小于7吧你搞个gep干什么。gep是大于等于!兄弟!换了!
jellyhk 发表于 2011-12-10 21:58



    其实我原来的代码是这样的,
  1. :import
  2. echo 你要处理的博客地址:
  3. echo 1. 新浪 2. 163 3. soho
  4. set /p var=请输入一数字:
  5. if "%var%" gep "7"
  6. (
  7. echo 请重新输入不大于7的数
  8. goto import
  9. )
  10. else
  11. (
  12. for /f "tokens=1 delims=," %%1 in ("新浪,163,soho") do set/p  Url=%%var%%
  13. echo %Url%
  14. goto import
  15. )
复制代码
但是输入数字后直接跳出,是语法不对的原因吧!
搞到兄弟误会了
作者: jellyhk    时间: 2011-12-11 11:42

本帖最后由 jellyhk 于 2011-12-11 11:43 编辑

楼上!你代码有错误!
第5段gep是什么东东?应该是geq!
还有for语句没搞懂你写的什么!你搞个tokens=1为什么里面没用到%%1;而且好象差2个括号!还差pause
  1. else
  2. (
  3. for /f "tokens=1 delims=," %%1 in ("新浪,163,soho") do (set/p  Url=%%var%%
  4. echo %Url%
  5. pause
  6. ::你不停顿那不直接跑到上面去了?
  7. goto import
  8. )
复制代码

作者: lyc309    时间: 2011-12-11 16:01

楼上!你代码有错误!
第5段gep是什么东东?应该是geq!
还有for语句没搞懂你写的什么!你搞个tokens=1为什 ...
jellyhk 发表于 2011-12-11 11:42



    恩,谢谢兄弟的热心,这只是测试代码搞不懂的话,就给个最简单的也有停顿的,也不跳转,用geq。就是打印数字。但是窗口也是直接退出
  1. set /p var=请输入一数字:
  2. if "%var%" geq "7"
  3. (
  4. echo 请重新输入不大于7的数
  5. pause
  6. )
  7. else
  8. (
  9. echo %var%
  10. pause
  11. )
复制代码

作者: jellyhk    时间: 2011-12-12 10:32

楼上!
你上面的代码为什么错误?因为你格式乱来!郁闷你!
看好格式!
if ....(...
)else(
..
)
你都把括号乱放了!它能当一条代码么?你以为机器是你自己啊!知道是一条代码!
  1. @echo off
  2. set /p var=请输入一数字:
  3. if "%var%" geq "7" (
  4.       echo 请重新输入不大于7的数
  5.       pause
  6. )else (
  7.       echo %var%
  8.       pause
  9. )
复制代码

作者: cjiabing    时间: 2011-12-12 15:10

看了半天看得头晕,你还是把原代码发出来吧。并且,你输入数字时不能按空格键!
作者: cjiabing    时间: 2011-12-12 15:26

本帖最后由 CrLf 于 2011-12-12 16:17 编辑

按标准流程操作,如果失败再说:
  1. :start
  2. echo 1、新浪
  3. echo 2、网易
  4. echo 3、人人
  5. set input=
  6. set /p input=输入序号:
  7. if "%input%"=="" goto start
  8. for /l %%a (1,1,10)  do if %%a==%input% goto well
  9. echo bad and try
  10. pause
  11. goto start
  12. :well
  13. echo;%input%
  14. pause
复制代码

作者: CrLf    时间: 2011-12-12 16:17

回复 13# jellyhk


    他可能把 bat 与 vbs 的语法搞混了,哈哈
作者: lyc309    时间: 2011-12-12 21:02

多谢大家的热心解答,原来是我把格式写错了,最基本的都写错了!泪奔
作者: lyc309    时间: 2011-12-12 21:04

回复  jellyhk


    他可能把 bat 与 vbs 的语法搞混了,哈哈
CrLf 发表于 2011-12-12 16:17



    其实是别的语言,都怪我没细看基本的,以为结构都差不多
作者: lyc309    时间: 2011-12-12 21:12

按标准流程操作,如果失败再说:
cjiabing 发表于 2011-12-12 15:26



    我后来按照这个流程了解决了,就是想知道为什么错而已,)else(分开就不行了




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2