[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

【2】for 命令详解

FOR [/d|/r|/l|f] [[drive:]path] ["options"] %variable IN (set) DO command [command-parameters]

1.  参数缺省
    for %i in (cn dos 5 2 1 ! ??.* cmd\*) do echo %i
   //依次打印字符串:cn,dos,5,2,1,!,"当前路径下与??.*匹配的非隐藏文件全名","当前路径下cmd目录内所有非隐藏文件全名".这里用空格对元素进行分界.
   //对于? *这两个字符,for会当作通配符去匹配文件名,而不会显示这两个字符

2. 参数d 是dirctory目录的缩写,作用在于集合里有通配符时匹配目录名而非文件名.

    for /d %a in (cn dos  5 2 1 ! * cmd\*)  do echo %a
   //依次打印cn,dos,5,2,1,!,"当前路径下所有非隐藏目录的目录名" “当前路径下cmd目录内所有非隐藏目录名”
   
3. 参数r 是road路径的缩写,作用在于它将会给集合里的元素加上指定路径下的目录树(请注意目录树包含了隐藏目录,子母录)再打印
    for /r %windir% %i in (plp626 . *) do echo %i
   //依次打印"%windir%目录树\plp626" "%windir%目录树\." "%windir%目录树\相应的文件全名(注意相应目录内的文件不包含隐藏属性的!)"
   //当%windir%缺省时,默认为当前路径.

4.  参数l 是ladder阶梯的缩写,作用就是按照 "起步 步长 结束"的递进方式来循环,这三个元素必须是自然数,当步长为0时,将成为死循环.
    for /l %a in (-10 1 10) do echo %a
   //依次显示 -10 -9 ... 10 这句表示 开始之为-10 以步长为1递增,当递增到10时循环结束
   
5.  参数 f 这个很要紧,认真看,f是file文件的缩写,和其他参数不同,这一个参数就有3种用法,个个神通广大:

    5.1 集合的元素是文件名
         for /f "eol=; skip=3 tokens=2,3* delims=, " %a in (test_1.txt test_2.txt) do echo %a %b %c
       //会依次分析 test_1.txt test_2.txt 中的每一行,忽略以分号打头(eolith原始的,开头)的那些行,跳过(skip)前3行
         以","为界定符(delimit划界),显示第2个,第3个,和剩余的字符串(token记号).

    5.2 集合的元素是外部命令的输出结果
        for /f "delims=" %a in ('more test.txt') do echo %a
       //取消默认的分割符(空格)对more test.txt打印的结果进行逐行分析,空格也会成为有效字符串.
        for /f "tokens=*" %a in ('more test.txt') do echo %a
       //对more test.txt打印的结果进行逐行分析,由于此时默认的分割符为空格,行前的空格字符将不会显示.
       //请注意括号里这对单引号,它有执行的意思,将执行对象的输出作为"文件"分析,这就决定了对象的输出必须是写入内存的,如果它没有这样,比如将more test.txt改为start test.txt或着test.txt它将打开test.txt,而%a由于没有接收到回车符这个命令,....
       //两外,这个外部命令还支持复合句,比如:
       for /f %%a in ('if exist 1.txt ^(echo ++^) else echo -- ')do echo %%a

    5.3 集合的元素是字符串
        for /f "tokens=*" %a in (" cn dos 帅 !") do echo %a
        for /f "delims=" %a in (" cn dos 帅 !") do echo %a
      //这两句都会显示cn dos 帅 !但不同的是前者将cn前的空格略去,后者原样打印.
        对于5.1如果有个test 3.txt(文件名为test 3)即文件名含空格,得用双引号将它括起来以表示文件名正确解释.
       但是这样就成立5.3的字符串用法,为了解释器能正确解释,它是个文件名,而非字符串,得用关键字"usebakeq",
        下面这句显示文件test 3.txt的相关内容(默认分割符为空格)解释器会把test 3.txt当作文件名,而非字符串.
        for /f "usebackq" %i IN ("test 3.txt") DO echo %i

有时要对移动硬盘或u盘进行判断,用这个命令
  1. wmic logicaldisk get name,description,drivetype
复制代码
6. for 变量的扩充
      以C:\Documents and Settings\pp365\桌面\ 路径下的 "test.bat"为例,对for 语句的变量测试如下
      (这里是用%0为例,在for语句中可以用相应的变量代换0):
用百分号0得到本批处理文件的带双引号的自身完整路径:
"C:\Documents and Settings\pp365\桌面\test.bat"

用 百分号~0
打印结果: C:\Documents and Settings\pp365\桌面\test.bat
用 百分号~f0
打印结果: C:\Documents and Settings\pp365\桌面\test.bat
用 百分号~d0
打印结果: C:
用 百分号~p0
打印结果: \Documents and Settings\pp365\桌面\
用 百分号~n0
打印结果: test
用 百分号~x0
打印结果: .bat
用 百分号~s0
打印结果: C:\DOCUME~1\pp365\桌面\test.bat
用 百分号~a0
打印结果: --a------
用 百分号~t0
打印结果: 2008-03-05 15:51
用 百分号~z0
打印结果: 947
用 百分号~$PATH:0
打印结果: C:\Documents and Settings\pp365\桌面\test.bat
----------------可以用组合修饰符来得到多重结果:

用 百分号~dp0
打印结果: C:\Documents and Settings\pp365\桌面\
用 百分号~nx0
打印结果: test.bat
用 百分号~fs0
打印结果: C:\DOCUME~1\pp365\桌面\test.bat
用 百分号~dp$PATH:0
打印结果: C:\Documents and Settings\pp365\桌面\
用 百分号~ftza0
打印结果: --a------ 2008-03-05 15:51 947 C:\Documents and Settings\pp365\桌面\test.bat

[ 本帖最后由 Batcher 于 2009-3-18 20:21 编辑 ]
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

【1】很重要的set 命令

set共两个参数/a 与/p
直接键入"set" 会显示系统化境变量及当前环境变量,
而 键入"set p" 会显示所有以字母 P 打头的变量,并且以变量名排序
缺省参数的情况不用多说,注意两点
1.赋空值:
  set "a="
2.养成好的习惯,以免多赋值一个空格出错.
   比如:
        set str=abc
   时加上一对双引号
        set "str=abc"

对于/a 参数

/A 命令行开关指定等号右边的字符串为被评估的数字表达式。该表达式
评估器很简单并以递减的优先权顺序支持下列操作:

    ()                                - 分组
    ! ~ -                            - 一元运算符
    * / %                          - 算数运算符
    + -                              - 算数运算符
    << >>                        - 逻辑移位
    &                                - 按位“与”
    ^                                - 按位“异”
    |                                 - 按位“或”
    = *= /= %= += -=       - 赋值
      &= ^= |= <<= >>=
    ,                                 - 表达式分隔符

注意前提:
1. 8进制数0?(0<=?<=7)与16进制数0x?(0<=?<=15),首字符不为0者为10进制数.

2. /a参数只对-(2^31-1)至2^31之间整数进行操作(注意是xp版本).
这点可以用代码来测试:
  1. @echo off&setlocal enabledelayedexpansion
  2. :支持最大数为1.9950631168807583848837421626836e+3010
  3. set m=1
  4. for /l %%a in (1 1 10000) do (
  5.    for /l %%b in (1 1 %%a) do (
  6.       set /a m*=2
  7.       set /a n+=1
  8.       echo !m!=2^^^^!n!
  9.       if "!m:~,1!" == "-" echo !m!&set /a mm=!m!-1&echo !mm!=!m!-1 &pause&exit
  10. )  )
复制代码
一元运算符~ ! -

~取反
将-(2^31-1)至2^31看做一个数轴,"原点O"为0的左侧与-1的右侧
(此数轴可以看做一个首尾封闭的数轴,对2^31-1加1将得到-2^31)
这样可以将计算机里的二进制数(全是整数)的取反看做求"相反数"了:

-2^31 ...︺︺︺︺︺︺︺︺︺︺︺︺︺︺︺O︺︺︺︺︺︺︺︺︺︺︺︺︺︺︺... 2^31-1
                                            ... -3 -2 -1  0 1  2 3 ...                     
~[x]就表示[x]的反数
比如:
  1. set /a a=~-1
复制代码
%a%就等于0
  1. set /a a=~5
复制代码
%a%就等于-6

!取非
![非0正数]为0
![0]为1
比如:
  1. set /a a=!2
复制代码
%a%就等于0
  1. set /a a=!0
复制代码
%a%就等于1

"-"取负数
-[x]与数学上的-x是一致的,只是要注意发生溢出时的状况
比如:
  1. set /a a=-(-2147483648)
复制代码
%a%为-2147483648而非2147483648,这是因为2147483648已溢出:
2147483648=(2^31-1)+1

算术运算符 * / % ﹢ -
算术运算符: *  /   %          ﹢  - 分别对应
  数学符号: x ÷ mod(取余) +  -
需要注意的是"%"是在命令行下,而在bat中则要用%%

逻辑移位: << >>
注意在批处理中或命令行下要加上一对双引号""或用^对<,>进行转义.
set /a [x]"<<"[y]
表示对[x]的二进制数左移[y]位
比如:
  1. set /a a=15"<<"1
复制代码
%a%就等于30
这是因为:15=bin(00 00000 00000 00000 00000 00000 01111)
左移1位就成了bin(0 00000 00000 00000 00000 00000 011110)
而bin(0 00000 00000 00000 00000 00000 011110)=2^4+2^3+2^2+2^1=30

经过简单的数学推导就可以知道:
[x]"<<"[y]==[x]*2^[y]
[x]">>"[y]==[x]/2^[y](注意溢出)

同理">>"就是右移,原理一样,这里略.

逻辑 "异", "或", "与": "^", "|", "&"
注意在批处理中或命令行下要在运算符前加上^
这里的:                ^            |             &    对应于
离散数学上的: 异或⊕     析取∨     合取∧
规则: 合取∧(有0则0)  析取∨ (有1则1) 异或⊕ (同0反1)
比如:
  1. set /a a=15^^5
复制代码
%a%就等于10
这是因为:
     01111
⊕) 00101
─────
=)  01010
而bin(01010)=10

对于"|", "&"原理一样,这里略.

赋值运算符
"=" 这个不用说了
对于 *= /= %= += -= &= ^= |= <<= >>
拿"+="为例,其他同理.
这只是一种简写
比如下面两行代码等效:
  1. set /a a+=2
  2. set /a a=a+2
复制代码
表达式分隔符","
这个运算符可以用来简化代码:
比如:
  1. set /a a=1
  2. set /a b=2
  3. set /a c+=3
复制代码
就可以简写为:
  1. set /a a=1,b=2,c+=3
复制代码
  1. @echo off
  2. ::分数化小数,徒手除法
  3. set/a a=1,b=7
  4. set/a c0=a/b, r0=a%%b*10
  5. set/a c1=r0/b,r1=r0%%b*10
  6. set/a c2=r1/b,r2=r1%%b*10
  7. set/a c3=r2/b,r3=r2%%b*10
  8. echo %c0%.%c1%%c2%%c3%
  9. pause
复制代码
另外:
set /a ... 与 set /p ...
可以省略掉set 与 /之间的空格写成
set/a ... 与 set/p ...
关于这类省略空格的用法,还有不少,后续再补充.
set/a的指针用法(有点像指针姑且这么叫吧):
数值定义:
  1. @echo off
  2. call:arr arr 1 2 3 4 + d d+ 258 68 944 ddd pp dd
  3. set arr
  4. pause
  5. :arr
  6. set/a n+=1
  7. if %2.==. goto:eof
  8. set %1%n%=%2
  9. shift /2
  10. goto:arr
复制代码
统计字符串中各种字符出现次数:
  1. @echo off
  2. set "str=aferefwfwerergrgreaaffwafwa"
  3. set/p= %str% 中有<nul
  4. :loop
  5. set /a %str:~0,1%+=1&set str=%str:~1%&if defined str goto loop
  6. echo  a %a% 个
  7. pause
复制代码
关于参数/P
1.接收键盘的输入
  1. @echo off
  2. :begin
  3. SET /p a=请输入一个字符串:
  4. echo %a%
  5. goto begin
复制代码
注意能用来作为变量的字符不能是常量数字,可以是字母,汉字等,及其字符串.
当输入特殊字符^&|<>时,前要加上^,否则出现语法错误.
语句"SET /p a=请输入一个字符串:"
类似c++里的:
  1. cout << "请输入一个字符串:\n";
  2. cin >> a;
复制代码
2.接收文件的首行.
这个用下面两个代码可以理解%0表示批处理本身:
代码一:
  1. :::::::::::::::::::
  2. @echo off
  3. set /p a=<%0
  4. echo %a%&pause>nul
复制代码
代码二:
  1. ::::::&color 02
  2. @echo off
  3. set /p a=<%0
  4. echo %a%&pause>nul
复制代码
3, set/p 特殊用法 .
左对齐(注意代码中的是制表符):
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%i in (1 10 999) do (set/a n+=1&set /p=^%%i <nul
  3. if !n!==5 set n=0&echo.
  4. )
  5. pause
复制代码
删回车符延迟(也可用ping)显示:
  1. @echo off
  2. for /f "tokens=*" %%i in (1.txt) do echo.|set /p=%%i
  3. pause
复制代码
删除1.txt每行的回车符后输出到2.txt里(拼成一行):
  1. @echo off
  2. for /f "tokens=*" %%i in (1.txt) do set /p=%%i<nul >>2.txt
  3. pause
复制代码
一般地set /p 的这种用法都会与|或<nul 联系起来.
<nul使得输出的最后一个字符没有换行符,这点很有用.
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

返回列表