zoukankan      html  css  js  c++  java
  • Bat脚本学习-4:Oracle自动备份还原脚本

    从同事那弄到一份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%OracleAutoBackupconfig.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!
            )
        )
    )

    写了很多注释,以便理解

  • 相关阅读:
    2016.04.18 view中嵌套两个居中的 lable
    2016..4.06 点菜系统案例:利用文本框的inputView和inputAccessoryView串联UIPickerView、UIDateP...
    2016.04.06 UITabBar+badge.h
    2014 .04 .06 navbar
    2016-03-17 leaks 内存泄露
    2016-03-16 sdwebimage
    2016-03-16 字符串的包含
    2016-03-16 键盘的弹出与收起
    2016-03-15 nsfoundation 数组 字典 nsrange等
    2016-03-15 uitextview placehold
  • 原文地址:https://www.cnblogs.com/liuyouying/p/7143289.html
Copyright © 2011-2022 走看看