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!
            )
        )
    )

    写了很多注释,以便理解

  • 相关阅读:
    The formatter threw an exception while trying to deserialize the message in WCF
    通过Web Deploy方式部署WCF
    The Managed Metadata Service or Connection is currently not available
    How to create Managed Metadata Column
    冒泡算法
    asp.net core 实战项目(一)——ef core的使用
    Vue学习笔记入门篇——安装及常用指令介绍
    Vue学习笔记入门篇——数据及DOM
    Vue学习笔记目录
    Chart.js在Laravel项目中的应用
  • 原文地址:https://www.cnblogs.com/liuyouying/p/7143289.html
Copyright © 2011-2022 走看看