bat programming is easy and powerful
用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的更多相关文章
- CF The World Is Just a Programming Task (Easy Version)【分析·思维】
题目传送门 题意: 给定一个括号序列,随意交换两个位置的括号之后,问有多少个不同长度的圈.关于圈的定义大概就是:将括号序列的后$k$个数放到括号序列的最前面,就是长度为$k$的圈.(看了好久题意emm ...
- Teach Yourself Programming in Ten Years
Teach Yourself Programming in Ten Years——用十年教会自己编程 作者:Peter Norvig 译者:刘海粟 本文原文为:http://norvig.com/21 ...
- Jquery Easy UI初步学习(一)
Easy UI 1.3.2 以前听说Easy UI很不错,当了一个dome,闲着没事就看了一下,也整理一下为了自己更好的记忆,也希望对象我这样小菜有帮助吧 先从后台管理的主页面开始,如要要做主页需要了 ...
- (转) [it-ebooks]电子书列表
[it-ebooks]电子书列表 [2014]: Learning Objective-C by Developing iPhone Games || Leverage Xcode and Obj ...
- 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 ...
- Python框架、库以及软件资源汇总
转自:http://developer.51cto.com/art/201507/483510.htm 很多来自世界各地的程序员不求回报的写代码为别人造轮子.贡献代码.开发框架.开放源代码使得分散在世 ...
- Awesome Python
Awesome Python A curated list of awesome Python frameworks, libraries, software and resources. Insp ...
- Machine and Deep Learning with Python
Machine and Deep Learning with Python Education Tutorials and courses Supervised learning superstiti ...
- 40 JavaScript Chart and Graph Libraries for Developers--reference
reference:http://www.egrappler.com/javascript-chart-and-graph-libraries-for-developers/ BY TEAMEGRAP ...
随机推荐
- OpenCV Start
开始学习opencv了. 从官网下载了 opencv-3.0.0-alpha.exe(windows版本) opencv-3.0.0-alpha.zip (linux版本) 从windows版本的安装 ...
- ASP.NET MVC 5 入门教程 (3) 路由route
文章来源: Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc-5-get-started-route.html 上一节:ASP.NET MVC 5 入门 ...
- HoloLens开发手记 - Unity之World Anchor空间锚
World Anchor空间锚提供了一种能够将物体保留在特定位置和旋转状态上的方法.这保证了全息对象的稳定性,同时提供了后续在真实世界中保持全息对象位置的能力.简单地说,你可以为全息物体来添加空间锚点 ...
- C#中的yield return与Unity中的Coroutine(协程)(上)
C#中的yield return C#语法中有个特别的关键字yield, 它是干什么用的呢? 来看看专业的解释: yield 是在迭代器块中用于向枚举数对象提供值或发出迭代结束信号.它的形式为下列之一 ...
- [BZOJ1876][SDOI2009]superGCD(高精度)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1876 分析: 以为辗转相减会TLE呢……但是好像没这个数据……就这么水过去了…… 辗转 ...
- [bzoj1296][SCOI2009]粉刷匠(泛化背包)
http://www.lydsy.com:808/JudgeOnline/problem.php?id=1296 分析: 首先预处理出每一行的g[0..T]表示这一行刷0..T次,最多得到的正确格子数 ...
- 温故知新---重读C#InDepth(一)
一本好书,或是一本比较有深度的书,就是每次研读的时候都会有新的发现. 好吧,我承认每次读的时候都有泛泛而过的嫌疑~~ 这几年一直专注于C#客户端的开发,逐步从迷迷糊糊,到一知半解,再到自以为是,最后沉 ...
- Moqui学习之代码分析mantle priceServices.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- This software is in the pub ...
- Ibatis对日期的处理
最近在项目中出现两种情况(因为项目比较早,经历各个版本的改动,所有设计不一致),第一种:数据库中某一字段为Date类型,对应的bean中的类型为java.util.Date,所有在对应的映射中会出现字 ...
- G-nav-04
'use strict';define([ 'jquery'], function($) { var nav = { init : function() { $("#burger-menu& ...