从同事那弄到一份Oracle自动备份还原的脚本,看上去很强大,苦在bat语法不熟,查了半天文档,先弄明白了一小段
@echo off REM 在批处理中,我们可以用setloacl ENABLEDELAYEDEXPANSION这个命令来启用"延迟环境变量扩展" REM 在我们启用了"延迟环境变量扩展"后,当CMD在解释涵有嵌套格式的命令时,他会把嵌套的命令一条一条的先执行一次,然后再进行匹配操作 REM 这样我们的赋值操作就会完成.并且再"延迟环境变量扩展"启用后,CMD会用!号来判断这是不是一个变量 REM 如没启用来变量用%name%这样的格式判断,启用后就用!name!这样的格式判断了,这个符号我们需要注意! setlocal ENABLEDELAYEDEXPANSION ::读取配置文件 echo 正在读取配置文件... set "base64=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" REM 假如执行一个命令,但是不想在屏幕里看到这个命令的执行情况,可以使用"[命令]>nul"就可以屏蔽命令在屏幕上的输出 REM 但是有的命令执行会出错,即使用了">nul"也不能屏蔽命令产生的信息,所以就在后面加" 2>nul"这个 REM 就是"[命令]>nul+空格+2>nul",这样,不管命令是否正确的运行,都不会在屏幕看到这个命令所产生的屏幕显示了。 REM 此处作用是在系统目录下新建一个文件夹,如果已经存在会报错,但被nul屏弊了,不会看到错误提示的输出 md %windir%\OracleAutoBackup >nul 2>nul set configFile=%windir%\OracleAutoBackup\config.ini set i=0 REM 文件不存在的话,就新建并输出一个换行符 REM .表示换行,>表示输出到文件 if not exist %configFile% echo.>%configFile% REM delims=后面的字符的意识是,将文本每一行的内容以delims=后面的字符分割成若干列. REM delims=后面可以是多个字符,可以是空格,也可以什么都没有. REM 什么都没有代表什么呢?就是不以任何东西为分割符,也是整行的内容了. REM 因为for默认是以,;和空格作分割符的, 所以一般要取得整行内容通常会用"delims="这样的形式来取消for的默认分割符. for /f "delims=" %%x in (%configFile%) do ( REM i为全局变量 if !i!==0 set bak_hou=%%x if !i!==1 set bak_lot=%%x if !i!==2 set bak_dir=%%x REM gtr表示大于 REM set/a表示数字运算 REM call表示调用函数 if !i! gtr 2 ( set/a gup=!i!-2 call :base64_str "%%x" set ora[!gup!]=!val! ) set/a i+=1 ) cls ::取默认值 REM ^ 表示行首,"^step"仅匹配 "step hello world"中的第一个单词 REM $ 表示行尾,"step$"仅匹配 "hello world step"中最后一个单词 REM *号表示重复的次数为零次或者多次 REM ^[0-9]*$表示纯数字 REM || 可同时执行多条命令,当碰到执行正确的命令时,将不再执行后面的命令。如果一直没有正确的,则执行完毕 REM && 可同时执行多条命令,当碰到执行错误的命令时,将不再执行后面的命令。如果一直没有错误的,则执行完毕 REM &同时执行多条命令,不管命令是否执行成功 REM 所以这两句意思是如果是空,则赋值;如果是数字,则不赋值,保留原值 if "!bak_hou!"=="" set bak_hou=3 echo !bak_hou!|findstr "^[0-9]*$">nul || set bak_hou=3 if "!bak_lot!"=="" set bak_lot=7 echo !bak_lot!|findstr "^[0-9]*$">nul || set bak_lot=7 REM %cd%表示当前文件夹(执行时所在文件夹),%~dp0表示批处理文件所在文件夹 if "!bak_dir!"=="" set bak_dir=%cd%\数据库备份 REM "delims=" 的含义是取消默认的分隔符,所以会把行上的内容照搬下来 REM 而 "tokens=*" 表示获取行上的所有内容,但是会忽略行首的所有空格。 REM %~fI - 将 %I 扩充到一个完全合格的路径名,这个I其实就是我们在FOR带入的变量,此处为x for /f "tokens=*" %%x in ("!bak_dir!") do set bak_dir=%%~fx if not exist !bak_dir! md !val! >nul 2>nul ::去掉格式错误的数据库连接配置项 set j=0 for %%i in (1,2,3,4,5,6,7,8,9) do ( REM && 可同时执行多条命令,当碰到执行错误的命令时,将不再执行后面的命令。如果一直没有错误的,则执行完毕 set ora[%%i]>nul 2>nul&& ( REM set后面不赋值表示清空变量 set ora_cur= REM usebackq 是一个增强型参数,当使用了这个参数之后,原来的for语句中第一个括号内的写法要做如下变动: REM 如果第一个括号里的对象是一条命令语句的话,原来的单引号‘要改为后引号`; REM 如果第一个括号里的对象是字符串的话,原来的双引号"要改为单引号‘; REM 如果第一个括号里的对象是文件名的话,要用双引号"括起来 REM tokens=1-3”表示1至3列,后面疑是%%a,怎么会是%%b? for /f "usebackq delims==. tokens=1-3" %%a in (`set ora[%%i]`) do set ora_cur=%%b set ora[%%i]= REM \/表示转义的/ echo !ora_cur!|findstr "\/">nul 2>nul && echo !ora_cur!|findstr "@">nul 2>nul && ( set/a j+=1 set ora[!j!]=!ora_cur! ) ) )
写了很多注释,以便理解
原文:http://www.cnblogs.com/liuyouying/p/7143289.html