批处理基础学习.docx

上传人:b****4 文档编号:4693508 上传时间:2022-12-07 格式:DOCX 页数:12 大小:28.69KB
下载 相关 举报
批处理基础学习.docx_第1页
第1页 / 共12页
批处理基础学习.docx_第2页
第2页 / 共12页
批处理基础学习.docx_第3页
第3页 / 共12页
批处理基础学习.docx_第4页
第4页 / 共12页
批处理基础学习.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

批处理基础学习.docx

《批处理基础学习.docx》由会员分享,可在线阅读,更多相关《批处理基础学习.docx(12页珍藏版)》请在冰豆网上搜索。

批处理基础学习.docx

批处理基础学习

[一日一教学](12)字符串查找:

find

  当我要查找字符串的时候,第一个想到的命令,并不是我在本文中要讲解的find,而是比它更强悍的命令findstr。

  我对findstr是如此的依赖,以至于当我向各位讲解find命令的时候,我还得老老实实地在cmd窗口中敲下find/?

这条命令,然后重重地按下回车键。

  find/?

的执行结果很快,唰的一下,帮助信息全出来了,与findstr命令10多个开关比起来,find仅有5个开关,算得上小巫见大巫了。

  find命令的基本格式是这样的:

find"要查找的字符串"要查找的文件,在这里,"要查找的字符串"这个内容是必不可少的,引号也是必须的。

例如:

find"bathome"d:

\test.txt,表示在D盘根目录下的文本文件test.txt中查找含有bathome这一字符串的所有行。

  find的结果将会有两种情况:

  1、当文件中包含要查找的字符串时,将返回这个字符串所在位置的整行内容,具体格式为:

第一行是"----------×××"(×××表示被查找的文件名,不包括引号对),第二行开始才出现包含字符串的整行内容;

  2、当文件中没有出现要查找的字符串时,find的结果仅仅返回"----------×××"这一行内容(×××表示被查找的文件名,不包括引号对)。

  在查找指定字符串的时候,有的场合需要区分大小写,有的场合则对大小写并不在意,如何实现这些需求呢?

  很简单,在find的时候,添加或取消/i开关就是了,具体用法为:

find/i"Abc"test.txt表示不区分大小写,文本内容中含有Abc、abc、ABC之类的都算;find"Abc"test.txt则严格区分字符大小写,只能匹配Abc,而不能匹配abc、ABC之类的字符。

  有时候,我们的需求并不是为了查找到某个字符串,而是要检测哪些行不含有特定的字符串,这个时候,可以使用开关/v,用法为:

find/v"Abc"test.txt,它表示查找那些不含字符串Abc的行(Abc要区分大小写),如果不区分abc的大小写,那么,应该写成find/i/v"Abc"test.txt。

  有时候,我们的要求很简单,仅仅只是想统计包含某个字符串的行总共有多少,这个时候,应该使用开关/c,写成find/c"abc"test.txt。

  如果要在每行的行首显示行号,怎么办?

那就写成find/n"abc"test.txt吧,它会把test.txt的内容都显示出来,与原文不一样的是,在每行内容的行首,都加上了行号——注意,它仅仅是在显示的时候加上行号而已,并没有真正改写文件的内容。

  如果你看到这样的命令:

find/i/v/n"Abc"test.txt,请一点要先沉住气,不要被众多的开关弄得眼花缭乱吓趴下了,仔细对照上面的解释,相信你很快就会理解它的功能:

在test.txt文件中,查找不包含字符串Abc的所有行,并在行首标上这些行的行号,查找的时候,字符串Abc不区分大小写。

  要是使用这样的语句:

find/c/n"abc"test.txt,会出现什么样的结果呢?

答案是:

开关/n会被忽略掉,最终结果不会显示带行号的行内容,只会显示匹配的总行数而已。

  echoabcdef|find"abc",见过这种写法吗?

它的含义是:

在字符串abcdef中,检测是否存在字符串abc,也就是说,find支持管道符号,把管道符号之前的语句的执行结果,作为指定字符串的查找对象,甚至,你可以使用这样的语句:

find"abc"test.txt|find"xyz",它表示在test.txt中查找同时存在字符串abc和字符串xyz的行,只要你愿意,你可以继续用管道符号把这个find语句连接下去,我们把这个过程称为多重过滤。

  在前面,我们说过,在find"要查找的字符串"要查找的文件这条命令语句中,引号是必须的,要是我们要查找的内容就是双引号本身,那又该怎么办?

  答案很简单:

把双引号本身先用双引号转义,再放到双引号对中,写成find""""test.txt的格式,如果要查找两个连续的双引号,则应该写成find""""""test.txt。

  如果你想查找两行之间的字符块,我劝你趁早放弃这个疯狂的想法,因为,find仅仅针对位于同一行上的字符串,不能查找跨行的字符块。

  与findstr命令相比,find的功能确实有限得多,仅仅因为不支持正则表达式这一点,就有不少人把它视为鸡肋,从而遭到无情的抛弃。

  然而,find并非一无是处,凭借自己的独门绝技,在与findstr的竞争中,它挣得了一席之地。

  这些独门绝技是什么呢?

(感谢BatCoder的提醒和zqz0012005的补充)

  1、统计含指定字符串的总行数。

find/c"abc"test.txt可以统计test.txt中含有字符串abc的总行数,而findstr则没有直接提供该功能,需要配合for语句才能实现;

  2、find可以读取Unicode格式的文本,而findstr则不行;

  3、find可以过滤某些特殊字符,而findstr则不行,比如,我们在使用fsutilfsinfodrives语句查询磁盘分区的时候,如果想让盘符分行显示而不是显示在同一行上的时候(这在用for语句提取盘符的时候很有用),find可以大显身手,而findstr只能干瞪眼了,具体语句为:

复制内容到剪贴板

代码:

fsutilfsinfodrives|find/v""

[一日一教学](11)移动文件(夹):

move

move,英文含义为“移动”,在批处理中,它可以把文件或文件夹从A处移动到B处。

很多时候,我看到有人在回复“如何把文件从A处移动到B处”的时候,给出的建议往往是:

先用copy命令复制文件,然后用del和rd删除文件和文件夹。

回复者根本没有想到,他给出的操作流程太繁琐了,他根本没有意识到,系统已经提供了直接移动文件的命令move!

  move的使用非常简单,基本格式为moveAB。

在这里,A表示你想要执行移动操作的文件或文件夹,B表示A被移动后保存的位置,而A可以使用相对路径,也可以使用绝对路径,甚至可以使用通配符,但是,在move执行移动文件的功能的时候,B只能是目录路径,而不能是文件路径——很难想象,你要把a.txt文件移动到b.txt文件里去,操作系统会做何感想。

比如:

movea.txtd:

\test,表示把当前目录下的a.txt移动到d:

\test目录下;movec:

\test.txtd:

\,表示把C盘根目录下的test.txt文件移动到D盘根目录下;movec:

\*.txtd:

\表示把C盘根目录下的文本文件移动到D盘根目录下。

  另外,需要特别注意的是:

move不能跨分区移动文件夹。

感谢zqz0012005的提醒。

  上面已经说过,如果你想把a.txt移动到b.txt文件里去,操作系统肯定会很不高兴。

  如果你确实要这么干呢?

  movea.txtb.txt!

  你会发现,对于你的胡缠蛮搞,操作系统也没拦着你,它很顺从地执行了你的命令,但是,结果并没有像你所期望的那样,把a.txt放进b.txt里面去,而是把a.txt改名为b.txt了。

  原来,在moveAB这样的命令中,move具备移动文件(夹)的基本功能,还兼有重命名文件(夹)的功效,具体起什么作用,视情况决定:

引用:

  1、如果A、B同为文件夹名,则把A移动到B目录下;

  2、如果A为文件名,

    ①B为文件夹名的时候,将把A移动到B目录下;

    ②B为文件名的时候,将把A重命名为B;如果B所在的位置为另一目录,则表示在把A移动到B所在的目录下的同时,重命名为B。

  一旦你明白了move的这些用法,重命名文件的时候,你将会很容易在ren和move之间做取舍:

如果只是单纯地重命名文件,则ren和move任选其一即可,只是move的写法显得有点怪异而已;如果在要移动文件之后,还要重命名文件,选择movec:

\test.txtd:

\abc\1.txt的写法将一步到位,而先movec:

\test.txtd:

\abc之后,再rend:

\abc\test.txt1.txt的写法将显得繁琐,最不可取的做法,是先copy,再del/rd,最后再ren,这是追求代码至精至简的人士所不能容忍的铺张浪费行为。

  有时候,move的过程并不会一帆风顺,比较常见的情形是:

目的地有重名文件存在,系统找不到指定的文件。

  先说重名文件的情况。

  如果有重名文件出现,move不会成功,它会很体贴地询问你:

改写××吗?

(Yes/No/All):

其中,××表示目的地的重名文件。

如果选择Yes,将覆盖重名文件;如果选择No,则放弃move操作;如果选择All,则在批量move的时候,如果存在同名文件,将不再询问是否覆盖,而是直接覆盖掉重名文件。

  如果你嫌跳出这个提示信息很麻烦,而你的真正目的是强行覆盖所有的重名文件的话,给move加上个/Y的开关,写成move/yAB就可以了——在cmd窗口中,默认情况下,move是带/-y  开关的,也就是默认会出现重名文件的提示信息,只不过这个默认开关是可以省略的;而在批处理脚本中,move默认带的是/y开关,不会出现重名提示而直接覆盖同名文件,和cmd窗口中的情形正好相反。

  再来看系统找不到指定文件的情况。

  有时候,你会很奇怪,moveAB的时候,A明明是存在的,为什么还要不知趣地提醒你:

“系统找不到指定文件”呢?

这不是在张口说瞎话么?

  不过,微软也挺无辜的:

出错的情形太多了,要我对每一种出错情形都给出明确具体的原因,我哪有那么大的神通呀?

我们搞技术的也不容易啊,能提醒你找不到指定文件,我们已经尽力了,您老就多多包涵一下吧。

  得了,我们还是自己动手找原因吧。

  原来,move没有dir的神通,它不能够识别出带隐藏或系统属性的文件,在这些文件面前,它成了瞎子,不过,这不能说move太无能,而是微软为了安全起见,限制了很多危险命令对带有隐藏或系统属性的文件进行直接操作——del、ren都是这副德性;而rd命令,则属于漏网之鱼,是个例外,要不然,微软的系统就不会有打补丁一说了。

  如何解决这一难题呢?

  没办法,只能老老实实地先用attrib命令去掉这些文件的隐藏或系统属性,再来move吧。

至于在写批处理的时候,如何判断哪些文件需要先attrib之后再move,哪些文件可以直接move,则不属于本文要讨论的范畴,还请读者关注论坛的其他相关讨论话题。

[一日一教学](10)删除文件夹:

rd

  前面的教程中介绍过,删除文件用的是del命令,那么,是不是像ren命令通吃文件和文件夹一样,del是不是也可以删除文件夹呢?

  答案是否定的,因为删除文件夹必须使用rd命令,这叫术业有专攻^_^。

  rd的另外一个写法是rmdir,源自ReMakeDirectory。

使用的方法也很简单:

rd文件夹名即可,例如:

rdtest。

它支持带路径的文件夹名,例如:

rdd:

\test。

  有时候,rd并不能很好地完成任务:

你让它删除test文件夹,它却傲慢地向你翻白眼:

目录不是空的。

不过,这也不能怨它偷懒不干活,只是它的脾气有点怪:

如果要删除的文件夹下面还有子文件,你得给rd戴顶高帽,加个/s参数,它才会高高兴兴地帮你做事,所以,正确的写法是:

rd/stest。

  如果你是个彻头彻尾的懒鬼,光是使用rd/stest,可能还是对它不甚满意,因为当你在删除带子文件的文件夹的时候,CMD总是不识时务地停下来,殷勤地问你:

是否确认(Y/N)?

非得等你输个字符敲下回车不可。

命苦不能怨政府,点背不能怨社会,谁叫rd有那么大的威力呢,它一旦耍起流氓来,那是谁也拦不住的——rd有风险,删除须谨慎啊。

好在微软对那些对删除十分有把握而又懒得要命的家伙体贴入微,提供了一个十分方便的参数/q,它取自quiet,官方解释为:

安静模式,带/S删除目录树时不要求确认。

这次再试试:

rd/q/stest,真个是:

弹指一挥间,灰飞烟灭,是不是有眼不见心不烦的酣畅感?

[一日一教学](8)重命名文件(夹):

ren[2009.2.26更新]

  ren取自rename的前三个字母,name在英文中有“为……取名”的意思,而re是前缀,有“重新做某事”的含义,结合起来,rename就是重命名的含义。

  ren的用法很简单,其使用格式为:

ren旧文件新文件名。

例如,把test.txt改写为abc.txt,使用rentest.txtabc.txt即可。

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

例如:

需要修改d:

\test\abc.txt这个文件的名字为xyz.txt的话,如果当前路径位于d:

\test,那么,命令可以写成:

renabc.txtxyz.txt、rend:

\test\abc.txtxyz.txt,但是,绝对不能写成rend:

\test\abc.txtd:

\test\abc.txt这样的格式。

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

  虽然ren的用法很简单,但是,它的功能却很强大,这主要得益于ren支持*和?

这两个通配符:

*表示任意多个字符,?

表示一个字符。

例如,要把所有的以.txt作为后缀名的文件改为以.doc作为后缀名,使用ren*.txt*.doc即可,简简单单的一条语句,瞬间就改动了大量的文件,CMD命令简洁而又不失强大的特点在这里体现得淋漓尽致。

又例如,要把以abc字符串打头、并且只有5个字符的txt文件改名为以xyz字符串打头,那么,可以这样写:

renabc?

?

.txtxyz?

?

.txt。

  需要引起高度重视的是,ren在使用通配符的时候,它的匹配规则十分奇特且过于复杂,不适合新手理解,在此不再展开做详细的解释。

若想了解其中的详情,请参考这篇帖子:

这是不是ren的一个bug?

-

  对于文件夹,ren同样适用。

  ren还有一个十分奇特的属性:

当文件具备隐藏属性或系统属性的时候,ren将不起作用,需要把文件的隐藏或系统属性去掉方可更名,对只读属性的文件,ren可顺利更名。

这在很多时候给我们制造了很多麻烦:

当你不知道要即将更名的文件是否具备隐藏或系统属性的时候,直接ren是很成问题的,;如果希望在重命名文件的时候,还必须保持原有的文件属性,则更加让人痛苦万分。

  怎么办?

  如果不介意文件的属性是否被改动,那么,保险的做法是,用attrib-s-h命令先去掉文件可能存在的系统属性或隐藏属性,然后再ren之;如果还要求更名后的文件要保持原有的属性的话,高效的做法是:

先用for语句中的%%~ai扩展获取原文件的属性,经过处理之后保存到变量中去,然后用attrib-s-h去掉文件可能存在的系统属性或隐藏属性,ren之后,再读取保留在变量中的属性值,用attrib恢复原有的文件属性。

[一日一教学](7)删除文件:

del[2009.2.12更新]

  删除文件使用的命令是del,它的全称是delete。

(另:

erase与del等效,感谢yslyxqysl提醒)

  del命令的用法很简单,使用"del文件路径"的格式就可以了。

比如,想删除D盘根目录下的test.txt,使用deld:

\test.txt即可。

  但是,并不是所有的文件都可以只用del命令就可以搞定,比如具有隐藏属性、只读属性或者系统属性的文件,假如d:

\test.txt具有隐藏属性,如果仅仅是deld:

\test.txt的话,d:

\test.txt会纹丝不动。

如何删除它?

这时候,就需要对del加上一些辅助参数了,隐藏属性是hidden,使用del/a:

h,只读属性是read,使用del/a:

r,系统属性是system,使用del/a:

s,如果不知道文件是什么属性,那么,使用del/a即可——不过有一种情况是例外,当文件具有只读属性的时候,还得添加del/a/f参数,所以,如果要对不知道属性的文件进行强制删除,使用del/a/f语句是最保险的做法。

在这里,/f  参数表示强制删除只读属性文件的意思,f取自force,也就是强制的意思。

  有段时间,威金病毒肆虐网络,以摧枯拉朽之势毁灭了不少文件,其中,最关键的一点是在每个目录下生成了一个desktop.ini文件,只要把这些desktop.ini文件删除,这个病毒就没有了危害性。

要删除每个目录下的desktop.ini文件,如果点开一个个的子文件夹删除的话,将不胜其烦,如果使用del命令,简单的一条语句就可以搞定,那就是:

在指定目录下执行del/a/f/sdesktop.ini命令。

在这里,/s表示搜索当前目录下的所有子文件夹,并删除指定文件的意思,s取自sub,表示“从属的”、“子目录的”的含义。

  删除文件是件十分危险的事情,稍有不慎,就可能删掉了重要的文件,所以,在执行删除操作的时候,需要小心谨慎。

如果需要在删除之前进行确认的话,可以添加一个参数:

/p。

  当然,对于十分有把握的删除操作,并不需要逐一确认的,可以选择静默删除模式,这时候,需要使用参数:

/q,也就是quiet的缩写形式

[一日一教学](6)复制文件:

copy

  copy,中文含义为“复制”,一个很容易见名知意的命令,它的作用是复制文件,用法十分简单:

copy源文件目的路径。

  假设,你需要把d:

\test\test.txt这个文件复制到D盘根目录下,那么,使用copyd:

\test\test.txtd:

\就可以轻易办到。

  当然,这是最简单的情形,在实际使用中,还是会碰到十分复杂的情况的。

  如果D盘根目录下已经存在了一个名为test.txt的文件,那么,复制过去的时候,copy命令就会提示你是覆盖原文件、是放弃复制还是覆盖所有文件。

如果你在批量复制的时候,一概覆盖原文件,那么,一个一个地选择十分麻烦,这个时候,你可以使用不加提示就覆盖原文件的参数/y(相当于自动选择了Yes选项),完整的命令为copy/yd:

\test\test.txtd:

\。

  如果复制的时候,你还需要把源文件改个名,比如把test.txt改为1.txt的时候,可以直接使用:

copyd:

\test\test.txtd:

\1.txt这样的命令,也就是说,在指定目的路径的时候,直接指定文件名,那么,新的文件名就是源文件复制之后的名字。

  如果要复制的路径带有空格、&等特殊符号的时候,请使用引号把这些特殊字符括起来,比如:

copy"d:

\testabc\test.txt""d:

\t&est"

  copy命令除了“复制”文件的功能外,还有一个绝活:

合并多个文件为一个文件,具体的格式为:

copy文件1+文件2+文件3+……目的路径\新文件名。

例如:

copyd:

\test.txt+d:

\abc.txtd:

\test\test.txt,那么,就把D盘根目录下的test.txt和abc.txt两个文件的内容合并为test.txt,并保存到d:

\test目录下。

  copy还有一些参数,但是常用的就上面的用法,更多的用法请在命令行窗口中使用copy/?

来查询,很容易上手的。

  必须注意的是,copy只能复制文件,对于文件夹的复制,则需要另请高明,动用xcopy来复制。

xcopy是copy的高级版本,有更丰富的参数,能实现更加复杂的功能,通吃文件和文件夹的复制,以后将另行介绍,在这里就不展开讲解了。

[一日一教学](5)流程跳转:

goto

  一般的批处理命令,都是按照自上而下的流程逐行执行的,也就是说,只有第一行的命令执行了之后,才可能执行第二行,第二行执行完之后,再执行第三行……如此依次执行。

  如果对不同的情况,需要执行不同的既定操作,若还是按照常规的执行流程的话,是无法完成任务的,这个时候,就需要引入流程跳转的概念,动用流程跳转语句goto了。

流程跳转的含义是:

改变默认的执行顺序,强制跳转到指定的位置执行特定的程序块。

  先来看个例子:

假设需要判断用户输入的是A还是B,代码可以写成这样:

复制内容到剪贴板

代码:

@echooff

set/pinput=请输入字母A或B:

if"%input%"=="A"gotoA

if"%input%"=="B"gotoB

pause

exit

:

A

echo您输入的字母是A

pause

exit

:

B

echo您输入的字母是B

pause

exit

  按照一般的执行流程,所有的代码都会自上而下逐行执行一次,结果将显示"您输入的字母是A"和"您输入的字母是B"这两行内容,很显然,这是达不到我们的要求的;但是,实际的结果是:

如果您输入的字母非A即B,则结果只会显示"您输入的字母是A"或者"您输入的字母是B";也就是说,代码的执行顺序发生了改变,不再一成不变地自上而下逐行执行了:

当输入字母A后,将执行第一条if语句,此条语句执行后,将跳转到标签段:

A,从而绕过了第一条if语句和:

A之间的所有代码行;当输入字母B后,将执行头两条if语句,当执行完第二条if语句后,将跳转到标签段:

B,从而绕过了第二条if语句和:

B之间的所有代码行。

  从上面的例子可以看到,要让goto语句起作用,还需要:

A或:

B之类的标签段的配合。

所谓的标签段,就是这样的一些代码块:

在首行上以单个冒号打头,其后紧跟一串字符,第二行及其之后的所有行为代码语句行。

在这里,第一行的冒号是标签标志,紧跟它之后的字符串是标签名,两者合称标签。

goto语句后面的部分为标签名,指引着该语句执行完之后该跳到转何方,标签则接收goto语句的跳转指令,引导着goto语句的后续操作。

goto语句和标签互相呼应,在实现流程跳转时相辅相成,缺一不可。

  下面说一下使用跳转语句goto的注意事项:

  1、goto语句和标签要互相呼应,不能只有goto语句而没有相应的标签段,否则,程序将找不到相应的标签段而直接退出;只有标签段而没有goto语句是允许的,但不能实现流程跳转功能,从代码精简的角度来看,有标签段而没有goto语句,则此标签是多余的,可以精简掉;

  2、若有多个标签段,则需要注意标签段之间是否需要添加合适的退出语句来终止程序继续向下执行,这是很多新手很容易犯错的地方,需要谨慎。

以上面这段代码为例,如果去掉:

A和:

B之间的exit语句,那么,当输入字母A之后,结果将同时显示"您输入的字母是A"和"您输入的字母是B"这两行内容,而保留exit语句将只会在显示"您输入的字母是A"后,按任意键推出批处理程序,因为批处理是自上而下逐行执行的,即使用goto语句跳转之后,在新的位置上,这一执行流程仍然会保持,直到碰上另一个流程跳转语句,执行过程并不会在两个标签段之间自动终止。

  3、标签名只可以使用常量,而

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1