DOS快餐店(六)

 
文件移形换位大法
 
■掌柜的
 
√ren和replace命令的使用
 
√利用脚本实现目录同步
 
掌柜的最近竟然迷恋起了网络游戏(以下简称网游),每天一下班总忍不住在游戏里“拼杀”一番。可
 
是经常碰到的一个头痛问题是,网游由于版本更新的需要,每过几天甚至几小时都需要对游戏文件在
 
线更新一次,往往兴冲冲地启动游戏却出现在线更新的界面,然后等到花儿也谢了却仍在更新。正在
 
万般头痛之时,喜欢“严打”员工上班偷懒的掌柜发现小伙计也玩这个游戏,并且是上班的时候玩!
“你是不是经常更新游戏?”掌柜的问。
 
小伙子显然有些措手不及,差点把心爱的笔记本都摔了:“……嗯,我……”
 
“不用说了,以后替我更新游戏的重任就交给你了,我不希望再看到更新界面,不然,哼哼,旧账新
 
账一起算……”掌柜的阴笑着说。
 
还好小伙计是批处理高手,我们来看看他是怎么做的。
 
1.在掌柜的机器上
 
第一步:点击“开始→设置→控制面板→用户账户”,并在其中新建一个管理员账户updater(用户名可
 
随意更改,但不得与现有用户名冲突,并应与下文中的脚本对应),将该账户的密码设置为“12345678
 
”(不含引号,实际使用中请更改为强度更高的密码)。
 
第二步:打开“我的电脑”,找到游戏的安装目录,右击该目录选择“共享和安全”(插入图a)。然后
 
在弹出窗口默认打开的“共享”选项卡中选择“共享此文件夹”,将“共享名”设为“game”(不含引
 
号)(见图1)。
 
第三步:点击“权限”按钮,在弹出窗口中点击“添加”,点击“选择用户或组”窗口的“高级”按钮
 
,然后点击“立即查找”,在下方的列表中选中刚才新建的updater,点击“确定”(见图2)。此时在
 
“选择用户或组”窗口的列表中已经显示出了我们添加的账户了,再次点击“确定”。
 
第四步:重新回到“game的权限”窗口,选中updater,在下方的“updater的权限”列表中勾选择“完
 
全控制”(见图3),依次点击“确定”关闭窗口。
 
2.在小伙计的机器上
 
打开“记事本”,输入以下脚本并保存为gameup.bat(掌柜的IP为192.168.0.2,小伙子的游戏安装目
 
录为d:\game):
 
@echo off
 
net use z: \\192.168.0.2\game "12345678" /user:"updater"
 
cd d:\game
 
for %%i in (*.*) do if not exist "z:\%%i" copy %%i "z:\" /y
 
replace *.* "z:\" /u/r
 
net use z: /del
 
每当自己更新完游戏,小伙子总是习惯性地执行一下这个脚本,掌柜的感到非常满意。
 
 
重要说明:
 
(1)以上脚本中添加管理员权限账户仅为了避免因权限问题带来的连接问题,也可使用其他用户组(关
 
于net use命令及连接故障的解决,请参见本期的《连根拔起——共享的二次登录》)。
 
(2)此脚本仅更新游戏主目录的文件,可根据游戏中的目录结构自行添加需要更新的子目录,如需要追
 
加更新game\p_w_picpaths,则在“net use z: /del”语句前添加如下语句:
 
cd d:\game\p_w_picpaths
 
for %%i in (*.*) do if not exist "z:\p_w_picpaths\%%i" copy %%i "z:\p_w_picpaths" /y
 
replace *.* "z:\p_w_picpaths" /u
 
 
本期配料:ren/replace 适宜人群:没有DOS基础的初学者
 
1.ren
 
在Windows中重命名文件时,我们一般采用右击该文件选择“重命名”或两次单击文件名的方式。而在
 
DOS中,则需要使用ren命令。文件名相当于人的称谓,比如在DOS快餐店中喊“掌柜的”,大家都知道
 
是指我。而ren命令的目的,就是要让大家改口,比如改为“老板”,让大家知道“老板”这个称谓是
 
指我,而“掌柜的”不再指我。同样的,文件名和称谓一样,只在一定范围内有效,比如在DOS快餐店
 
里的“掌柜的”是我,而VBScript快餐店、JavaScript快餐店的“掌柜的”则是其他人。在别的地方
 
找我就得将我的具体位置也描述出来,如“DOS快餐店的‘掌柜的’”,就好像我们在一个目录下打开
 
其他目录中的文件时就必须给出此文件的完整路径。
 
目标:将D:\a.txt命名为D:\b.txt
 
ren d:\a.txt b.txt
 
命令格式:ren 要重命名的文件路径 新文件名
 
命令讲解:如果要重命名的文件不在当前目录,则命令参数中的“要重命名的文件路径”就必须是完整
 
路径,如上文中的“d:\a.txt”,在当前目录下则可省略路径而只需给出文件名,如上文中可省略为
 
“a.txt”。另外,新的文件名只要符合文件命名规范,就能自由更改,文件扩展名也能重命名,如“
 
ren d:\a.txt b.bak”。
 
 
2.replace(在Windows 98中没有此命令)
 
当我们在“资源管理器”中进行文件复制、粘贴操作时,如果目标目录中存在与要复制的文件同名的
 
文件,就会出现是否将“文件替换为”的提示框。这和我们以前介绍过的copy命令有些共同点,但
 
replace的职能就是“替换”,它还具有子目录替换、版本控制等功能,下面就让我们来体验一下。
目标1:用D:\a.txt替换D:\backup下的同名文件
 
replace d:\a.txt d:\backup
 
命令格式:replace 源文件路径 目标文件所在目录
 
命令讲解:如果源文件在当前目录中,我们也可以省略掉完整路径而只使用文件名,而第二个参数是同
 
名文件所在目录名,不包含文件名。
 
当目标目录中并没有源文件时,默认情况下replace命令就不会进行替换,如果需要目标目录也包含这
 
个文件,则必须使用copy命令或replace命令的参数。
 
 
目标2:用replace命令将D:\a.txt添加到D:\backup
 
注意:此处假设D:\backup目录中不包含a.txt,参数/a不能与/s、/u搭配使用。
 
replace d:\a.txt d:\backup /a
 
命令格式:replace 源文件路径 目标文件所在目录 /a
 
命令讲解:每个命令都有很多参数,我们在记忆时要掌握窍门,比如此处的/a即为“add”(添加)的缩
 
写。此命令参数只有在目标目录不包含源文件同名文件的情况下使用,否则会提示“未添加文件”。
在学习了replace命令的基本使用以后,可能你会迫不及待地尝试一下,但你可能仍会遇到文件存在却
 
无法替换(显示“拒绝访问”)的问题,这是什么原因呢?
 
 
目标3:用D:\a.txt替换D:\backup下的同名只读文件
 
replace d:\a.txt d:\backup /r
 
命令格式:replace 源文件路径 目标文件所在目录 /r
 
命令讲解:和上一个参数一样,此处的/r可记忆为“read only”(只读)。顾名思义,使用/r参数就是
 
为了告诉replace命令:即使目标文件是只读的,照删不误!
 
小提示
 
如果不使用/r参数,我们也可以用attrib命令去除目标文件的只读属性,方法为“attrib -r 
 
d:\backup\a.txt”,此命令将在本栏目今后的文章中详细讲解,敬请关注。
 
 
是否还记得上期曾提到过的pause命令?它可以使脚本暂停,直至按下任意键才继续。而在replace命
 
令中,我们可以使用一个参数来简化这个操作,仅用一条命令就能实现两条命令的功能。
 
 
目标4:等待用户按下任意键后,用D:\a.txt替换D:\backup下的同名文件
 
replace d:\a.txt d:\backup /w
 
命令格式:replace 源文件路径 目标文件所在目录 /w
 
命令讲解:用replace/?命令查看replace参数时,我们发现/w参数的解释为“等您插入磁盘以后再运行
 
”。可是经过测试后发现,如果在未将磁盘插入A:(软驱)时,使用“replace d:\a.txt a:\”仍会提
 
示错误。与其说是等待插入磁盘,倒不如说这是一个等待参数,我们可以将/w理解为“wait”(等待)
 
。在使用了该参数后,replace命令在对文件进行替换操作前将首先暂停操作并提示“按任意键继续”
 
。注意,就如我们刚才所说的那样,如果源文件路径和目标文件目录不正确的话,命令会直接报错,
 
也就是说在暂停之前命令就对路径参数进行了检查。
 
如果目标目录中有多个子目录,并且每个子目录都有需要替换的文件,我们应该怎么办呢?大家可能
 
会想到使用cd命令频繁切换目录,然后配合replace命令进行操作,但我们有更好的办法。
 
 
目标5:用D:\a.txt替换D:\backup及其子目录下所有的同名文件
 
replace d:\a.txt d:\backup /s
 
命令格式:replace 源文件路径 目标文件所在目录 /s
 
命令讲解:默认情况下,如果D:\backup的子目录中含有与源文件同名的文件(如:d:\backup\1\a.txt、
 
d:\backup\2\a.txt),replace命令将不对它们进行替换,参数/s可以理解为“subfolder”(子目录)
 
。使用了/s参数后,replace命令就在目标目录中进行搜索,对该目录下所有的子目录进行遍历,查找
 
所有要替换的文件。
 
在进行遍历替换等多文件操作时,我们最担心的就是误操作所带来的数据丢失,如何能让替换操作开
 
始前提示确认一下呢?
 
 
目标6:在目标5的基础上,要求确认操作
 
replace d:\a.txt d:\backup /s /p
 
命令格式:replace 源文件路径 目标文件所在目录 /p
 
命令讲解:如同以前介绍过的copy命令一样,replace的操作确认参数也是/p,建议在使用/s参数的时
 
候搭配使用。
 
我们进行文件替换的目的很多情况是为了将修改过的新版本文件替换旧版本文件。但如果文件较多(如
 
本文开始处介绍的游戏文件更新)时,就很难把改动过的文件和未改动的文件区分开来,无奈之下只好
 
使用全部替换。在文件数据量大的时候,这种操作无疑是对系统资源和时间的浪费,这种缺点在网络
 
传输时尤为明显(本文开头的游戏更新就是采用net use命令将网络主机上的共享目录映射为本地盘符
 
z:,然后再进行数据传输,也属于网络传输)。
 
 
目标7:用D:\a.txt替换D:\backup目录下的同名文件,如果目标文件版本较新则不替换
 
replace d:\a.txt d:\backup /u
 
命令格式:replace 源文件路径 目标文件所在目录 /u
 
命令讲解:参数/u可以理解为“update”(更新/升级),既然是更新当然不能用旧文件替换新文件咯。
 
所以/u参数就是告诉replace命令,在进行替换操作之前,先对源文件和目录文件的修改时间进行比较
 
,如果源文件比目标文件版本新(理想的状况)则进行替换,否则不进行替换。使用这个参数也可以在
 
一定程度上防止我们误将文件覆盖为老版本,现在可能会有朋友提出疑问:为什么文章开始处的游戏文
 
件更新脚本中没有全部使用replace/u,而用copy命令进行了辅助?这是由于游戏更新过程中,不但有
 
文件的版本更新,更有可能会有一些新的文件产生(即源文件目录中有,但目标文件目录中没有的文件
 
),简单地使用/u参数则有可能会遗漏掉新生成的那部分文件。
 
 
本期大餐:改造游戏更新脚本,使其满足文件同步需要
 
适宜人群:有一定DOS基础的老鸟
 
目标1:支持自定义源、目标目录、文件类型的文件同步脚本
 
@echo off
 
cd %1
 
for %%i in (*.%3) do if not exist "%2%%i" copy %%i "%2" /y
 
replace *.%3 "%2" /u
 
使用方法:在“记事本”中输入以上脚本保存为filesyn.bat,用cd命令将当前目录转到该脚本的保存
 
目录中,使用格式为“filesyn.bat 源目录 目标目录 需要同步的文件类型”(不含引号)。如果源或
 
目标目录不是当前目录,请在参数中使用完整路径。
 
脚本讲解:以前我们曾经给大家讲过,%1、%2等变量表示批处理在运行时由用户指定的参数,如执行“
 
filesyn.bat d:\ e:\ txt”,则其中的第一个参数“d:\”即赋值给了%1,而“e:\”赋值给了%2,第
 
3个参数“txt”赋值给了%3。首先“cd %1”是指将当前目录转到第1个参数(即源目录参数)指向的目
 
录。第二句使用了for循环语句对当前目录进行了遍历,将其中文件扩展名符合参数%3的文件都找出来
 
,然后用exist语句检查目录目录(%2)中是否也有这个文件,如果(if)没有(not exist)此文件,就用
 
copy命令将它从源目录中复制到目标目录中。当遍历结束,批处理开始执行下一条语句,用replace语
 
句配合参数/u来对目标目录的文件进行更新,如果目标目录中包含了比源文件版本更新或者相同的文
 
件(包括上一条循环语句中复制到目标目录中的文件),则不更新。
 
 
DIY你的DOS菜
 
上期答案:
 
1.将当前日期和时间分两行存为c:\now.txt。
 
date/t >>c:\now.txt
 
time/t >>c:\now.txt
 
2.制作一个脚本,修改系统时间为16:30:00,运行c:\abc.exe,接着用网络时间同步命令将时间改回
 
来。
 
注意:仅适用于Windows XP。
 
time 16:30:00
 
c:\abc.exe
 
w32tm /resync /rediscover
 
3.将第8期“名师烹饪”中的脚本稍加修改,使其能够记录MSN Messenger使用情况。
 
按照原文件中的方法进行操作,将脚本位置改为MSN Messenger所在目录,将脚本中的echo语句后的内
 
容做相应的修改,将最后的“qq.exe”改为“msnmsgr.exe”(详细代码请参考上期原文)。
 
本期习题:
 
1.将D:\movies\new.rm重命为old.rmvb。
 
2.用D:\abc\1.exe替换D:\def目录及其子目录下的所有同名文件,要求操作确认。
 
3.在第2题的基础上,只替换旧文件。