<acronym id='vq30b'><em id='vq30b'></em><td id='vq30b'><div id='vq30b'></div></td></acronym><address id='vq30b'><big id='vq30b'><big id='vq30b'></big><legend id='vq30b'></legend></big></address>
<i id='vq30b'></i>
    <ins id='vq30b'></ins>

  1. <tr id='vq30b'><strong id='vq30b'></strong><small id='vq30b'></small><button id='vq30b'></button><li id='vq30b'><noscript id='vq30b'><big id='vq30b'></big><dt id='vq30b'></dt></noscript></li></tr><ol id='vq30b'><table id='vq30b'><blockquote id='vq30b'><tbody id='vq30b'></tbody></blockquote></table></ol><u id='vq30b'></u><kbd id='vq30b'><kbd id='vq30b'></kbd></kbd>

  2. <fieldset id='vq30b'></fieldset><span id='vq30b'></span>

        <i id='vq30b'><div id='vq30b'><ins id='vq30b'></ins></div></i>

          <dl id='vq30b'></dl>

          <code id='vq30b'><strong id='vq30b'></strong></code>

          WindowsBatchScripting_B

          • 时间:
          • 浏览:27
          • 来源:124软件资讯网

          Command-line arguments

          command-line arguments即 command-line parameters(下令行参数)在batch剧本中可以通过 %1, %2,....,%9来获取. 可以有多于9个的参数 – 参见 how to loop over all of them.

          %0语法不指向下令行参数, 而是执行batch文件自身.
          e.g. 测试是否提供了第一个下令行参数

          if not -%1-==-- echo Argument one provided
          if -%1-==-- echo Argument one not provided & exit /b

          使用 SHIFT(for each command-line argument, …)来更强壮地循环遍历下令行参数:

          :argactionstart
          if -%1-==-- goto argactionend
          echo %1 & REM Or do any other thing with the argument
          shift
          goto argactionstart
          :argactionend

          使用 SHIFT循环遍历下令行参数, 但不修改 %1, %2…

          call :argactionstart %*
          echo Arg one: %1 & REM %1, %2, etc. are unmodified in this location
          exit /b
          
          :argactionstart
          if -%1-==-- goto argactionend
          echo %1 & REM Or do any other thing with the argument
          shift
          goto argactionstart
          :argactionend
          exit /b

          将下令行参数通报给情况变量:

          setlocal EnableDelayedExpansion
          REM Prevent affecting possible callers of the batch
          REM Without delayed expansion, !arg%argno%! used below won't work.
          set argcount=0
          :argactionstart
          if -%1-==-- goto argactionend
          set /a argcount+=1
          set arg%argcount%=%1
          shift
          goto argactionstart
          :argactionend
          
          set argno=0
          :loopstart
          set /a argno+=1
          if %argno% gtr %argcount% goto loopend
          echo !arg%argno%! & REM Or do any other thing with the argument
          goto loopstart
          :loopend

          遍历所有下令行参数, 虽然不是个强壮(robust)的方案:

          for %%i in (%*) do (
            echo %%i
          )

          代码很优雅但不够强壮, 没有思量包罗通配符wildcards(*,?)的参数. 特殊是上面的下令会用切合的文件名替换包罗通配符(*,?)的参数, 或者没有文件切合的时间抛弃它们.
          不管怎样, 上面的循环在参数不包罗通配符的时间可以很好地事情.

          e.g. 非强壮方式, 找到下令行参数个数

          set argcount=0
          for %%i in (%*) do set /a argcount+=1

          再一次, 对于包罗通配符的参数不建立.

          按Windows Vista机械的测试履历, 参数个数最大可以到达4000. 在XP和Win7上个数可能差别.
          通报参数到batch剧本时, 参数使用的分开字符可以是:
          - space(空格)
          - comma(逗号)
          - semicolon(分号)
          - equal sign(即是号)
          - tab character(制表符)
          下面的下令行中的参数都是一样的:
          - test.bat a b c d
          - test.bat a,b,c,d
          - test.bat a, b, c, d
          - test.bat a;b;c;d
          - test.bat a=b=c=d
          - test.bat a b,c;,;=d
          纵然是 a b,c;,;=d也可以, 一系列的分开符可以被当做单个分开符.

          要将 space, comma, semicolon放入参数值中, 可以将值困绕在引号(quotation marks)中然后传入. 不外引号也变为参数值的一部门.
          当引用剧本中的参数时, 要将外面的引号剔除, 可以使用 %~ – 参见Percent tilde

          Parameters / Arguments at ss64
          Escape Characters, Delimiters and Quotes at ss64
          Using batch parameters at Microsoft

          Wildcards

          许多下令吸收文件名通配符–即并不代表自身意义的字符, 而是表现开启了文件名组的匹配模式.
          Wildcards(通配符):
          - *(asterisk)-星号: 任何字符序列
          - ? (question mark)-问号: 单个字符, 除了(.”), 或者是在一个maximum period-free(无句号)文件名的末尾的一系列问号的一部门, 可能是 zero number of characters(零个字符), 参见澄清的例子.

          ex.
          - dir *.txt
          匹配 Myfile.txt, Plan.txt以及其他有 .txt后缀的文件
          - dir *txt
          无需加入句号(period). 这可以匹配没有遵照句号约定的文件名, 如 myfiletxt.
          - ren *.cxx *.cpp
          将所有以 .cxx作为后缀名的文件, 重命名为 .cpp后缀的文件.
          - dir a?b.txt
          - 匹配 aab.txt, abb.txt. a0b.txt, etc.
          - 不匹配 ab.txt, 问号后面跟的字符不是单个问号或句号, 和zero character(零字符)不匹配.
          - 不匹配 a.b.txt, 问号无法匹配一个句号.
          - dir ???.txt
          匹配 .txt, a.txt, aa.txt, aaa.txt. 序列中的问号后面跟句号, 可以和 zero number of characters 匹配.
          - dir a???.b???.txt???
          匹配 a.b.txt. 当最后一个问号后面没有跟句号, 它仍然是在文件名的maximum period-free部门的一个序列.
          - dir ????????.txt & @REM eight question marks
          和 *.txt匹配的类似, 由于每个文件都有在 .txt前不凌驾8字符的短名称(short file name).

          短名称的离奇之处:
          通配符匹配同时会作用在长文件名, 以及隐藏的 short 8 chars+period+3 chars(8字符名.3字符后缀) 文件名上. 这样的意外情形会引起问题.

          不像其他操作系统的 shell, cmd.exe自身不会应用 wildcard expansion(通配符扩展) (将包罗通配符的pattern用匹配pattern的文件名替换). 这实在是每个法式处置惩罚通配符时的责任.
          这可以让 ren *.txt *.bat这样的下令事情, 由于 ren下令现实上看到的是 *通配符, 而不是一列匹配通配符的文件. 于是echo *.txt就不会显示当前文件夹下切合pattern的文件, 而是按字面意思显示 *.txt.
          另一个效果: 可以写 findstr a.*txt, 无需担忧 a.*txt被一些当前文件夹下的文件名替换掉. 另有, 可以递归findstr /s pattern *.txt, 在一些其他操作系统中, *txt 部门可能会被所找到的文件名所替换, 从而就无视了嵌套的文件夹.

          接受通配符的下令包罗: ATTRIB, COPY, DIR, FINDSTR, FOR, REN, etc.

          Wildcards at ss64
          Using wildcard characters at Microsoft

          User input

          可以使用下列要领来获得用户输入:
          - SET /P 下令
          - CHOICE ml
          - 使用 type con >myfile.txt, 对于多行的用户输入, 使用 Ctrl+Z来竣事.

          Percent tilde

          当下令行参数(command-line argument )包罗文件名, 可以用特殊语法来获取文件的种种信息.
          下面的语法扩展了以%1形式通报的文件的种种信息.

          Syntax Expansion Result Example
          %~1%1去除困绕的引号n/a
          %~f1盘符的全路径C:WindowsSystem32 otepad.exe
          %~d1盘符C:
          %~p1末尾带反斜杠的无盘符路径WindowsSystem32
          %~n1对于文件, 是不带路径和扩展名的文件名.
          对于目录则是目录名
          notepad
          %~x1包罗句号的文件扩展名.exe
          %~s1修改 f, n, x 以使用短名称n/a
          %~a1文件属性(attribute)–a——
          %~t1文件上次被修改的日期和时间02.11.2006 11:45
          %~z1文件巨细151040
          %~pn1p和 n的组合WindowsSystem32 otepad
          %~dpnx1多个字母的组合C:WindowsSystem32 otepad.exe
          %~$PATH:1当前PATH变量下的文件夹中找到的第一个匹配的路径,
          没有匹配的话返回空string
          n/a
          %~n0将 %~n应用到 %0; 不带扩展名的batch名称tildetest
          %~nx0将 %~nx应用到 %0; batch的名称tildetest.bat
          %~d0将 %~f应用到 %0; batch盘符C:
          %~dp0将 %~dp应用到 %0; batch的文件夹, 后面跟反斜杠C:UsersJoe Hoe

          FOR下令建立的相同语法可以作用于single-letter(单字母)变量, 如%%i. 更多信息可以参见 call /? 或 for /?.

          Parameters / Arguments at ss64
          Using batch parameters at Microsoft
          for at Microsoft

          Functions

          function(函数)即 subprogram(子法式)可以通过CALL, labels, SETLOCAL, ENDLOCAL来实现.
          e.g. 检测 arithmetic power(算术平方)

          @echo off
          call :power 2 4
          echo %result%
          rem Prints 16, determined as 2 * 2 * 2 * 2
          goto :eof
          
          rem __Function power______________________
          rem Arguments: %1 and %2
          :power
          setlocal
          set counter=%2
          set interim_product=%1
          :power_loop
          if %counter% gtr 1 (
            set /a interim_product=interim_product * %1
            set /a counter=counter - 1
            goto :power_loop
          )
          endlocal & set result=%interim_product%
          goto :eof

          在function最后的 goto :eof不是须要的, 通常存在凌驾一个function的时间他才是必须的.

          result变量可以在command line上生存以及指定:

          @echo off
          call :sayhello result=world
          echo %result%
          exit /b
          
          :sayhello
          set %1=Hello %2
          REM Set %1 to set the returning value
          exit /b

          上例中, exit /b 用来取代 goto :eof, 效果一样.

          Note: equal sign(等号) 是用来分开参数的. 下面各项都一样:

          call :sayhello result=world call :sayhello result world call :sayhello result,world call :sayhello result;world
          参见 Command-line arguments

          Calculation

          Batch剧本可以做简朴的32-bit integer arithmetic(整数运算) 以及 bitwise manipulation(比特位操作): 使用 SET /a下令. 支持的最大整数: 2147483647 = 2 ^ 31 - 1, 最小整数 -2147483648 = - (2 ^ 31), 通过赋值的trick来告竣: set /a num=-2147483647-1. 语法和老式C语言一样.

          算术操作包罗*, /, % (modulo), +, -. batch中的modulo(取模)必须输入 %%.

          Bitwise操作将数字解译为 32 binary digits(32位二进制数). 它们是 ~ (complement补), & (and与), | (or或), ^ (xor异或), << (left shift左移), >> (right shift右移).

          negation (取反)的逻辑操作是!: 0酿成1, 非0酿成0;

          combination(组合操作) ,: 允许一个set下令中有多个盘算.
          组合赋值操作的模式为: +=, 即 a+=b 意思是 a=a+b; a-=b 意思是 a=a-b; 类似的: *=, /=, %=, &=, ^=, |=, <<=, and >>=.

          precedence order(有限序次)
          1. ( )
          2. * / % + -
          3. << >>
          4. &
          5. ^
          6. |
          7. = *= /= %= += -= &= ^= |= <<= >>=
          8. ,

          字面量可以按如下输入: 十进制: decimal (1234), 十六进制 hexadecimal (0xffff, leading 0x), 八进制 octal (0777, leading 0).

          对于负数, 内部的bit表现是 two’s complement. 在算术运算和bit操作之间提供了一种联系; e.g. -2147483648 用 0x80000000表现, set /a num=~(-2147483647-1)发生 2147483647, 即是 0x7FFFFFFF(set /a num=0x7FFFFFFF)

          对于下令诠释器来说一些操作有特殊寄义, 表达式需要用引号困绕它们来使用:

          set /a num='255^127' set /a 'num=255^127'
          两种引号放置方式都可以 set /a num=255^^127
          使用 ^来转义 ^, 取代引号.

          ex.
          - set n1=40 & set n2=25
          set /a n3=%n1%+%n2%
          使用尺度百分号来举行变量扩展.
          - set n1=40 & set n2=25
          set /a n3=n1+n2
          有了 /a选项, 就无需在变量名上用百分号困绕
          - set /a num='255^127'
          将 ^”放在引号内里可以防止下令诠释器剖析到它的特殊寄义.
          - set /a n1 = (10 + 5)/5
          有 /a选项情形下, 等号 =前后的space不起作用.
          However, getting used to it lends itself to writing set var = value” without /a, which sets the value of var ” rather than var”.
          - set /a n1=2+3,n2=4*7
          两次盘算
          - set /a n1=n2=2
          和 n1=2,n2=2有一样效果
          - set n1=40 & set n2=25 & set /a n3=n1+n2
          和预期的一样.
          - set /a n1=2,n2=3,n3=n1+n2
          和预期的一样.
          - set n1=40 & set n2=25 & set /a n3=%n1%+%n2%
          除非n1和 n2预先设置好, 否则无法事情. %n1%” 和 %n2%”的变量规格会在第一个 set下令被执行前举行扩展. 去掉百分号则可以事情.
          - set /a n1=2,n2=3,n3=%n1%+%n2%
          除非n1和 n2预先设置好, 否则无法事情, 和上例的理由一样.
          - set /a n1=0xffff
          用16进制记号设置 n1.
          - set /a n1=0777
          用8进制记号设置n1.

          e.g. 打印prime numbers(质数):

          使用从2到n的开根的数作为除数 http://coolshell.cn/articles/3738.html

          @echo off
          setlocal
          set n=1
          :print_primes_loop
          set /a n=n+1
          set cand_divisor=1
          :print_primes_loop2
          set /a cand_divisor=cand_divisor+1
          set /a cand_divisor_squared=cand_divisor*cand_divisor
          if %cand_divisor_squared% gtr %n% echo Prime %n% & goto :print_primes_loop
          set /a modulo=n%%cand_divisor
          if %modulo% equ 0 goto :print_primes_loop & REM Not a prime
          goto :print_primes_loop2

          set at ss64.com
          set at Microsoft

          Finding files

          使用 DIR, FOR, FINDSTR, FORFILES, WHERE 来寻找文件.

          ex.
          - dir /b /s *base*.doc*
          输出当前文件夹下以及子文件夹下的文件, 扩展名前的文件名包罗”base”, 扩展名以”doc”最先, 包罗”doc”和”docx”. 文件输出全路径, 一行一个文件.
          - dir /b /s *.txt | findstr /i pers.*doc
          文件包罗全路径以及 findstr过滤下令所支持的有限的regular expression(正则表达式)的组合效果, 发生了一个多功效又强盛的组合, 可以通过文件名和目录名来寻找文件;
          - for /r %i in (*) do @if %~zi geq 1000000 echo %~zi %i
          当前文件夹以及子文件夹下, 文件size大于或即是1,000,000 bytes的, 以byte为单元输出文件size, 以及文件全路径. 对于%~zi语法, 参见 Percent tilde.
          - forfiles /s /d 06/10/2015 /c 'cmd /c echo @fdate @path'
          当前文件夹以及子文件夹下, 在2015/6/10及之后修悔改的文件, 打印文件修他日期和全路径. /d后面的日期花样以locale为准. 这样, 即可寻找最近修改的文件.
          - (for /r %i in (*) do @echo %~ti :: %i) | findstr 2015.*::
          在当前文件夹下递归查找, 输出最后修他日期在2015年内的文件. 将修他日期和事务放在double colon(双冒号::)前面. 只要Windows和locale版本是包罗four-digit年份的花样, 就可以事情.
          双冒号是为了确保 findstr下令和日期实时间匹配, 而不是文件名.
          - for /r %i in (*) do @echo %~ti | findstr 2015 >NUL && echo %i
          同上, 在2015年内修改的. 差别的是, 只输出文件, ,没有修他日期.
          - findstr /i /s /m cat.*mat *.txt
          通过内容查找文件. 通过 正则表达式cat.*mat实行全文本查找, 条件是所有以 .txt末端的文件, 输出文件名. /m开关确保只有文件名被输出.
          - where *.bat
          输出在当前目录以及 PATH目录下所有的 .bat文件.

          Keyboard shortcuts

          使用Win+R, 输入cmd.exe, 即可在尺度控制台(console)中使用Windows下令行, 这里有许多键盘快捷键, 包罗功效键:

          Tab: 当前文件夹下的文件名, 文件夹名补全. 可补全的部门通常是最后的 space-free(无空格)部门, 但若是用了引号就纷歧样了. 通常的下令都能补全文件和文件夹, 但 cd下令只对文件夹起作用. Up Down arrow: 从command历史中搜索下令, 每次一个. Escape: 擦除当前输入的下令. F1: 一个个字符地打出commad历史中上次输入的下令. F2: 请求输入一个字符, 会泛起command 历史中的上个下令的最短的前缀, 其中不包罗输入的那一个字符. e.g. 前一个下令: echo Hello world, 若是输入 o, 就泛起 ech. F3: 进入command历史中的前一个下令. 重复F3不起作用. F4: 请求输入一个字符, 以当前光标位置最先, 删除一直到所输入的字符(不包罗)中心的部门.e.g. 若是输入 echo Hello world, 光标在 H前, F4输入 w, 效果就是 echo world. F5: 进入command历史中的前一个下令. F6: Control+Z 字符. F7: 弹出一个command历史的字符列表, 可以用Up,Down选择下令, 回车直接执行. F8: 给出一个字符串, 会在command历史中征采以此字符串为前缀的下令以显示, 每次一个. F9: 输入数字, 按序号执行command历史中的下令. Alt + F7: 扫除command历史.

          上述也被以为是command prompt keyboard shortcuts.
          上述快捷键的可用性看起来与运行中的 DOSKEY无关.

          Windows Keyboard shortcuts at ss64.com
          doskey at Microsoft

          Perl one-liners

          有些使命可以用Perl one-liners利便地完成. Perl剧本语言源自另一个操作系统. 由于许多Windows情况安装了Perl, Perl one-liners对Windows batch剧本来说是自然兼容的后缀.

          ex.
          - echo 'abcbbc'| perl -pe 's/a.*?c/ac/'
          让Perl像sed(流编辑器)一样, 功效是使用正则表达式, 以支持文本替换.
          - echo a b| perl -lane 'print $F[1]'
          Perl当做cut下令, 显示列中第二个区域内容, 本例为 b. 使用 $F[2]显示第三块区域; 索引从0最先. Native方案是 FOR /f.
          - perl -ne 'print if /"hello"/' file.txt
          Perl当做grep 或 FINDSTR, 输出file.txt中切合if后面正则表达式的各行. Perl regular expressions比FINDSTR强盛许多.
          - perl -ne '$. <= 10 and print' MyFile.txt
          Perl当做 head -10 command, 输出文件中的前10行.
          - perl -e 'sleep 5'
          等候5秒.
          - for /f %i in ('perl -MPOSIX -le 'print strftime '%Y-%m-%d', localtime'') do @set isodate=%i
          将ISO花样的当前时间放入 isodate变量.
          - perl -MWin32::Clipboard -e 'print Win32::Clipboard->Get()'
          将文本内容输出到剪贴板. 把下令存储到 getclip.bat中, 就有了一个利便的 getclip下令来实现 CLIP.

          在网上, Perl one-liners经常在另一个操作系统中的command-line convention中贴出, 用单引号apostrophe (‘) 取代 Windows的quotation marks双引号. 这些都需要在Windows中调整.

          Perl One-Liners by Peteris Krumins at github.com
          Why doesn’t my Perl one-liner work on Windows? at stackoverflow.com
          W:One-liner program#Perl

          Limitations

          没有和Linux类似的 touch下令. 这里的 touch会修改文件的 last-modification timestamp (最后修改的时间戳), 而不会改变其内容.

          workaround, 可读性和可顺应性较差:
          - copy /b file.txt+,,

          Windows recursive touch command at superuser.com
          Windows version of the Unix touch command at stackoverflow.com

          —TBC—
          —YCR—