用linux的角度来思考windows,习惯了linux的shell后,

再来看windows的bat编程,就简单多了,简直就是理所当然

实际上windows的cmd命令行和linux的shell命令行感觉基本上差不多了
比如都有重定向 > , >>, 和管道 | 
ipconfig /a >> ip.txt
dir c: |more
tree c: | find "call" (tree显示的结果像图行,其实是字符串)

要习惯于看windows cmd的命令帮助,command /? ,里面的解释已经很详细很直白了

这就像linux下的man “command”

-----------------------

当你熟练掌握了linux中的sed, awk, cut,grep等这些行编辑命令后,
自然就能灵活地、得心应手地使用cmd中for if 等等命令的使用
for [/options] %var in (set) do command [command-parameters]

FOR /F "eol=; tokens=2,3* delims=, " %i in (...)...

cmd支持命令简写:
rd=rmdir,md=mkdir,ren=rename,
type:显示文本文件到标准输出,print是真的用打印机打印输出
prompt:修改命令提示符,对应linux bash中是设置环境变量ps的值

  用prompt命令,可以将cmd设置成类似bash的样子:>prompt [$d $t $p] #

move:移动文件,linux是mv命令
xcopy:复制文件和目录树
find:在文件内按行搜索字符串,linux中类似的命令是grep

-------------------------------------
cmd把命令后面的[options]叫开关switches,bash叫选项options
cmd的开关通常不能合并在一起书写,而bash的选项可以合在一起
find /V /N "somestring" filename
netstat -tunl |grep "telnet"

windows的系统命令一般放在%SystemRoot%\Windows\system32下,因此它就相当于
linux的/sbin, /bin, /usr/bin, /usr/sbin

命令shell中,每个命令执行完毕后,都会返回一个返回码,成功为0,失败为1.

echo %errorlevel%: linux中用$! 表示

------------------------------

变量延迟:

在由&,&&,||,()组成的符合句中,变量的值取该语句之前的值,在该符合句中可以给变量赋值,

但变量的新值,要在该语句的下一句才会生效,即:变量的值会“延迟“起作用

利用变量延迟,可以交换两个变量的值而不用中间变量;

要避免“变量延迟”的问题,使变量的新值在该复合句中即时生效,应该:

  setlocal enabledelayedexpansion

  .....  echo !delayed_var!

变量延迟的机制:

  因为bat执行命令的机制是:首先将一条命令读入内存,在执行该命令之前,先做一些预处理工作,包括:替换循环变量、

如:  

test]# for %i in (f1 f2) do ren %i %i.mp3  //执行时会首先将%i分别替换成f1, f2,然后才执行

test]# ren f1 f1.mp3

test]# ren f2 f2.mp3

  给该语句中的 “变量 %var%”赋值,这时候,因为这条语句还没有执行,所以当然是用该语句之前的值给

  变量赋值, 然后才执行这条语句。

为了让语句中的变量,能够及时感知环境的变化,使用“变量延迟”技术, 让语句在执行之前,再次对其中的变量赋值,...

事实上,在bat编程中,变量延迟也用得相当“普遍”,很平常的:凡是在for循环语句的结构体中,要改变“非迭代变量”的变量 的值,如

累加,字符串连续串接等,都要使用变量延迟

setlocal ...  注意和endlocal配合使用

bat中可以使用通配符?,*

?: 表示0个或1个字符,*表示0个或任意个,注意?可以是没有,可以是0,并不一定要有一个字符

如: dir /b ????? : 将匹配1到5个字符的所有文件(夹)

--------------------

在web,c,c++编程中,对于比较大的项目,往往会通过代码分割,写成多个文件

同样的,如果要用bat实现比较复杂的任务(以后习惯用bat脚本来实现处理 windows下的任务)时,

就要编写多个脚本.bat文件,这时相互之间的调用就要使用call命令...(但要注意call语句不同于函数调用,因为

它不会阻塞原程序的执行)

bat编程中,没有while...do的结构,要使用循环,是用 if...goto “lable"来实现的

同样,也没有switch...case的结构,也是用 if...goto “lable"来实现的

-----------------------------

if语句的逻辑与和逻辑或?

在bat编程中,不能用&& ||来表示逻辑与/或(有&&, ||,但它们是用来连接语句的), 要表示多个条件的 “逻辑与” 应该使用if语句的嵌套:

if "%str1" == "%str2" (

  if "%str3"== "%str4%" (

    rem do something....

)

)

choice命令?

有的windows中没有choice命令,因为choice不是内部命令,它是一个外部命令,choice.exe/choice.com

但是也没有必要,一定用choice命令,因为用set /p, if, goto 命令完全可以代替choice命令...

字符串的连接?

bat脚本中字符串连接直接挨着写就好了,不用什么+.

-------------------------------------

bat编程中的pushd和popd的有什么作用?

当需要在多个目录中反复切换时,使用pushd和popd是最好的方法,比cd命令更方便更直观

linux中的pushd和popd,dirs命令:

pushd parameter_dir  ====  “current_dir" pushd + cd  parameter_dir

cd -   其中的- :  = $OLDPWD

pushd; pushd +2; popd;  popd +1; 栈总是从上到下, 从0, 1,2 开始的,所以切换时总是整数+加号

dirs -c: 清除栈中所有的目录

popd命令总是不能清除当前正在使用的目录!

windows:  pushd %~dp0 ;  pushd “%~dp0test" ... popd:  即: 切换到某个目录,执行完某些操作后,再返回到原来的目录

--------------------------------------------

--------------------------------------------

for循环:

: for变量的扩展是“全局”的,即:跟使不使用/d, /r , /f等完全无关

:for的4种形式:包括:不使用扩展的纯的裸的、使用/d的、使用/l的、使用/f的,

每种格式都是有严格规定的,只能使用每种情况下规定的格式和许可的内容: 如:

for %%i in (*.mp3)/(*) do echo %%i  : 这个是可以的,可以使用通篇符,而且主要是使用通配符

for /f  %%i in (*.mp3)/(*) do echo %%i  : 这个就是不可以的,因为在for /f 的三种格式里都没有使用通配符

默认的for循环(不带任何扩展参数的时候) 只处理file-set,(将把set当作一个或一组文件,是文件)不处理目录

file-set的表示方法只有两种?!: 一种是使用通配符*,?, 另一种是直接输入文件名列表集合,用空格分割

file-set中并不能执行命令,不像linux中使用后引号表示命令执行结果,

(for命令的set集合中,要想使用 “子命令“的执行结果,需要使用 /f 扩展参数!!)

所以,即使你单或 双引号,for也只是认为那是几个文件的集合:

如: for %%i  in ( 'dir /b mp3') do (ren %%i %%i.mp3)      将会认为dir, /b, mp3是三个文件,

  将它们重命名,自然执行 ren /b /b.mp3就会出错了

for /d: 对这个参数,以前一直有个误解,认为只匹配文件夹,对文件不起作用。实际上,这种想法是错误的:

      1.  有这个/d与没有/d,对文件的解析完全是没有影响到,文件该解析该匹配的,照样匹配,照样执行命令就好象没有这个/d一样

      2. 只有当后面括号中使用通配符*, *.*, (????.????足够多?)的时候,才匹配目录,而不匹配文件,也就是说,只有/d跟* 在一起的时候,才起作用

for /r :  参数/r, 搜索指定路径及所有子目录中与set相符合的所有文件,注意是指定路径及所有子目录。

  1、set中的文件名如果含有通配符(?或*),则列举/R参数指定的目录及其下面的所用子目录中与set相符合的所有文件,无相符文件的目录则不列举。
  2、如果set中为具体文件名,不含通配符,则枚举该目录树(即列举该目录及其下面的所有子目录)(并在后面加上具体的文件名),而不管set中的指定文件是否存在。
  例:for /r c:\ %%i in (*.exe) do echo %%i --把C盘根目录,和每个目录的子目录下面全部的EXE文件都列出来了

    for /r c:\ %%i in (boot.ini) do echo %%i --枚举了c盘所有目录
    for /r d:\backup %%i in (1) do echo %%i --枚举d\backup目录
    for /r c:\ %%i in (boot.ini) do if exist %%i echo %%i --很好的搜索命令,列举boot.ini存在的目录

for /f:

前面的for都只是处理文件和目录,把它们作为一个整体进行处理,不涉及文件里面的内容,

但如果要对文件里面的内容进行处理的话,就要用/f 扩展,但并不表示for /f不能用来处理文件

而且只有这个时候,才能使用单引号,双引号,后引号等,才能使用 执行命令结果

for /f: 以前有一种误解:因为for /f要将file-set中的每个文件的内容要读入内存进行处理,所以就以为

  for /f就不能用来处理文件,只能用来处理文件的内容。其实for  /f同样可以用来处理文件,如:

  文件名的输出,文件的重命名,文件的复制删除等等,只不过这时我不需要、我可以忽略:文件内容的分割处理等结果

  我不处理那些%%j, %%k, 等等的“隐藏变量”, 我只处理%%i 这个基本的文件循环变量本身就可以了(这时的%%i

  代替的是文件本身,跟使用tokens的%i代表的是不同的!) 当然,当我需要对文件里面的内容进行解析、分割,

  并输出解析结果时,我可以要tokens, delims等等... 而且for /f格式也说得很清楚: for /f [“options”] %var in (3种格式)    do ... 那些分割解析的只是:[options]!

for  %i in (set) do格式只能使用通配符或一个一个的列举方式的fileset,

如果这两种方式都不适合,要用dir命令来列举的时候,就要使用: for /f %i in ('dir /b /a-d /s') do echo %i....

:最神奇的是,当tokens和%%cycle_var连用的时候, 在for /f "tokens=1,2,3,4" %i in ("this is a test") do echo %i %J %k %L中,隐含变量(%i后面的变量)是要分顺序的!只能是j,k,l...不能是其他字母或大写的字母,否则就无效!

如:上面的语句,只输出: this %J a %L    而且这里的%i代表的不再是文件名本身,而是分割后的tokens...

---------------------------------------

:dir 要只显示文件,就要把属性directroy过滤掉: dir /a-d, 要修改文件的属性,需要使用attrib命令...

:有时候,用*或者?也可以代替for循环?如对文件夹下的所有文件进行重新命名: 可以不使用for循环,直接用:

rename * *.mp3   // 增加扩展名

rename *.* *.mp3  // 全部扩展名更改为mp3

rename ????.txt ????.mp3

rename ?????????????????????????.txt  ?????????????????????????.mp3( ?问号越多, 可以命名的文件越多?)

这里要注意的是: 问号?是不能代替扩展名的.xxx, 在上面的命令中,使用rename ???? ????.mp3将是错误的???

: 通配符虽然可以代表任意字符, 但是 在一次循环中,前后代表的字符/文件/含义在当前这次循环/操作中,

  “通常”是一致的,"后面的可以替代前面的,但前面的*不一定就能代替后面的内容“,如:

    ren *.mp3  *   // 这个命令本意是要去掉文件的扩展名,但这样实际上文件是没有改变和影响到

:关于rename的“古怪"规定: 新的文件名不能带路径,即使跟原来的路径相同也不行:

(网上的说法:

旧文件可以使用绝对路径,也可以使用相对路径,但是,新文件名不能使用任何路径,只能是新的文件名,即使这个路径就是当前目录。

例如:需要修改 d:\test\abc.txt这个文件的名字为xyz.txt的话,如果当前路径位于d:\test,那么,命令可以写成:ren abc.txt xyz.txt、ren d:\test\abc.txt xyz.txt,

但是,绝对不能写成ren d:\test\abc.txt d:\test\abc.txt这样的格式。

之所以会有这个古怪的规定,可能是一旦把路径写成另外的目录,ren就具备了“移动文件+重命名文件”的功能 了,这和它的定位不相符(内部的代码编写就跟move重复了)。

:要遍历整个目录,dir命令的/S选项,以及for命令的/R选项都有遍历功能

: 很重要的一点是: 要对bat中的语句进行排错,一是在命令行一句一句执行,二是开启echo on 可以看到

  (交互式的)每一句执行的结果,清楚地看到是哪条语句出错

:注意两种变量的不同表示方法:循环变量用%%i表示,而普通变量用 %var%表示

--------------------------------------

bat举例:

rem @echo off
cls

setlocal enabledelayedexpansion
echo author: bkylee
echo date: %date%,%time%
echo functionality: batch to delete mp3 files extention
echo scenario: the command "ren *.mp3 *" can not bring about the result above
echo.

pushd %~dp0%

rem if not exist "mp3\" (
rem echo "error 1: no mp3 folder"
rem goto end
rem )

echo --------------------------------------------------
echo start to rename...

set warnings = ""

for %%i in (*) do (
if "%%~xi" == ".mp3" (
ren %%i %%~ni

rem ----: 在下面的else前后都必须有一个空格,使else与括号) else ( 相隔离,否则就会出错!
) else (
set warnings = !warnings!"%%i is not mp3 file"
)
)

echo --------------------------------------------------
dir /b

rem recover the enviornment before
echo.

echo %warnings%
echo.

endlocal

popd

:end
echo "press any key to exit ..." & pause >nul

资料来源于网络,其中,参考这篇文章,写得比较好,比较细:http://biancheng.dnbcw.info/python/341315.html

bat programming is easy and powerful的更多相关文章

  1. CF The World Is Just a Programming Task (Easy Version)【分析·思维】

    题目传送门 题意: 给定一个括号序列,随意交换两个位置的括号之后,问有多少个不同长度的圈.关于圈的定义大概就是:将括号序列的后$k$个数放到括号序列的最前面,就是长度为$k$的圈.(看了好久题意emm ...

  2. Teach Yourself Programming in Ten Years

    Teach Yourself Programming in Ten Years——用十年教会自己编程 作者:Peter Norvig 译者:刘海粟 本文原文为:http://norvig.com/21 ...

  3. Jquery Easy UI初步学习(一)

    Easy UI 1.3.2 以前听说Easy UI很不错,当了一个dome,闲着没事就看了一下,也整理一下为了自己更好的记忆,也希望对象我这样小菜有帮助吧 先从后台管理的主页面开始,如要要做主页需要了 ...

  4. (转) [it-ebooks]电子书列表

    [it-ebooks]电子书列表   [2014]: Learning Objective-C by Developing iPhone Games || Leverage Xcode and Obj ...

  5. How Will Java Technology Change My Life?

    How Will Java Technology Change My Life? We can't promise you fame, fortune, or even a job if you le ...

  6. Python框架、库以及软件资源汇总

    转自:http://developer.51cto.com/art/201507/483510.htm 很多来自世界各地的程序员不求回报的写代码为别人造轮子.贡献代码.开发框架.开放源代码使得分散在世 ...

  7. Awesome Python

    Awesome Python  A curated list of awesome Python frameworks, libraries, software and resources. Insp ...

  8. Machine and Deep Learning with Python

    Machine and Deep Learning with Python Education Tutorials and courses Supervised learning superstiti ...

  9. 40 JavaScript Chart and Graph Libraries for Developers--reference

    reference:http://www.egrappler.com/javascript-chart-and-graph-libraries-for-developers/ BY TEAMEGRAP ...

随机推荐

  1. OpenCV Start

    开始学习opencv了. 从官网下载了 opencv-3.0.0-alpha.exe(windows版本) opencv-3.0.0-alpha.zip (linux版本) 从windows版本的安装 ...

  2. ASP.NET MVC 5 入门教程 (3) 路由route

    文章来源: Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc-5-get-started-route.html 上一节:ASP.NET MVC 5 入门 ...

  3. HoloLens开发手记 - Unity之World Anchor空间锚

    World Anchor空间锚提供了一种能够将物体保留在特定位置和旋转状态上的方法.这保证了全息对象的稳定性,同时提供了后续在真实世界中保持全息对象位置的能力.简单地说,你可以为全息物体来添加空间锚点 ...

  4. C#中的yield return与Unity中的Coroutine(协程)(上)

    C#中的yield return C#语法中有个特别的关键字yield, 它是干什么用的呢? 来看看专业的解释: yield 是在迭代器块中用于向枚举数对象提供值或发出迭代结束信号.它的形式为下列之一 ...

  5. [BZOJ1876][SDOI2009]superGCD(高精度)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1876 分析: 以为辗转相减会TLE呢……但是好像没这个数据……就这么水过去了…… 辗转 ...

  6. [bzoj1296][SCOI2009]粉刷匠(泛化背包)

    http://www.lydsy.com:808/JudgeOnline/problem.php?id=1296 分析: 首先预处理出每一行的g[0..T]表示这一行刷0..T次,最多得到的正确格子数 ...

  7. 温故知新---重读C#InDepth(一)

    一本好书,或是一本比较有深度的书,就是每次研读的时候都会有新的发现. 好吧,我承认每次读的时候都有泛泛而过的嫌疑~~ 这几年一直专注于C#客户端的开发,逐步从迷迷糊糊,到一知半解,再到自以为是,最后沉 ...

  8. Moqui学习之代码分析mantle priceServices.xml

    <?xml version="1.0" encoding="UTF-8"?> <!-- This software is in the pub ...

  9. Ibatis对日期的处理

    最近在项目中出现两种情况(因为项目比较早,经历各个版本的改动,所有设计不一致),第一种:数据库中某一字段为Date类型,对应的bean中的类型为java.util.Date,所有在对应的映射中会出现字 ...

  10. G-nav-04

    'use strict';define([ 'jquery'], function($) { var nav = { init : function() { $("#burger-menu& ...