windows批處理BAT入門

  • 批處理

    • 說明

      • 面向程序編程.
    • 實際

      • 提高效率.
    • 內容

      • 若干指令.
      • 需要反覆執行.
      • 保存到文件中方便執行.
    • 啓動cmd

      • C:\Windows\System32下雙擊cmd.exe指令.
      • Win+r輸入cmd
      • win搜索cmd.
    • 特性

      功能 特點
      輸入 交互式,實時決策執行.
      判斷 for,if,while,switch都有.
      基本類型 數字,字符串,數組,函數
      匹配 正則表達式
      併發 默認串行,start並行.
      goto 指令跳轉
      位運算 與或非
      邏輯運算 and or not,大於小於等於
      字符串 子串,長度,替換,裁剪
      文件 存在判斷(if exist filename),修改屬性,創建刪除.
    • 延遲擴張

      • 兩種解析:一種是讀取一行就立即將%裏面的變量解析.但是這類在一些場景不合適.
      • 另一種是延遲擴張:即在執行語句的時候擴張. 這樣就允許組合表達式.
      • 類比makefilesecondexpansion.
  • 腳本

    • 文件名後綴

      • BAT

      • CMD

    • 執行

      • BAT雙擊執行.
      • cmd中執行.
    • 執行bat

      • cmd中輸入完整文件路徑.
      • cmd => cd /path/to/bat => xxx.bat
      • 修改環境變量PATH=%PATH%;path\to\bat => 執行xxx.bat. (和上面兩個一樣的效果)
      • 路徑下雙擊文件.
  • 常用指令

    • 腳本

      指令 作用 案例
      ver 當前msdos版本. cmd啓動時的第一行
      assoc 後綴綁定程序. .pdf默認用foxitreader打開.
      cls 清理屏幕 等價clear,cls清理屏幕和緩存
      path 環境變量,指定指令搜索路徑. echo %path%
      rem remark,表示註釋,不輸出,啥也不做.
      start 並行執行 開啓新的cmd窗口或程序
      driverquery 查看驅動詳情
      ipconfig 網絡信息管理,釋放和重新分配.查看信息等.
      systeminfo 查看系統信息,系統信息,處理器,網卡,內存
    • 編程

      指令 作用 案例
      pause 暫停,等待輸入任意符號. 常在腳本最後添加,查看執行輸出.
      prompt 設置提示欄 默認情況下,輸入前面是當前路徑.$G == >
      choice 從給定的選擇中任選一,一般是阿拉伯字母.
      title 命名窗口名稱.
      set 查看已經定義的所有變量及值
    • 文件操作,不涉及目錄

      指令 作用 案例
      copy 文件拷貝,不涉及路徑拷貝
      del 文件刪除,不涉及目錄 支持嵌套遞歸.del /s *.txt
      attrib 修改文件屬性 類似chmod.attrib +r file
      comp 比較兩個文件的大小.
      more 查看文件內容
    • 目錄操作

      指令 作用 案例
      cd 無參查看路徑,有參更換路徑. cd=pwd,cd xx=cd xx
      dir 查看路徑下文件和文件夾 類似ls.支持查看子文件dir /s
      md 創建目錄 類似mkdir,支持同時創建多個文件夾.
    • 文件和目錄

      指令 作用 案例
      move 移動或重命名
      rd 默認僅僅刪除文件夾,刪除文件夾前不能爲空./s刪除文件 默認文件夾操作,選項支持文件操作.
      ren 重命名,文件夾和文件都支持.
      find 從文件中搜索字符串
      xcopy 文件和文件夾都支持,建議用這個. sh=cp
      tree 樹形的方式查看文件夾子文件夾. tree可以分級,可以選擇是否查看文件.默認僅查看目錄.
    • 時間

      指令 作用 案例
      date 查看日期 echo %date%
      time 查看時間 echo $time%
    • 輸出

      • 開關

        • echo on:輸出執行的腳本。
        • echo off:不輸出執行的腳本。
      • @

        • 從當前指令開始生效。
        • 一般用於@echo off.
  • 代碼

    • 創建修改

      • notepad打開,輸入echo ok && pause,保存爲xx.cmd或xxx.bat.
      • 點擊文件,右鍵edit,編輯.
    • 命名

      • 儘量不要加空格.
      • 儘量不要和內部指令重名.
    • 執行和輸出

      • 說明

        • 指的是在cmd中不要輸出指令.
      • 普通

        指令
        dir /b
        
        輸出
        D:\money\battst>ait.bat
        
        D:\money\battst>dir /b
        ait.bat
        dd
        good
        
        D:\money\battst>
        
      • 關閉指令輸出

        關閉之後
        echo off
        dir /b
        
        輸出
        D:\money\battst>ait.bat
        
        D:\money\battst>echo off
        ait.bat
        dd
        good
        
        D:\money\battst>
        

        echo off沒有生效,執行後才生效所以輸出了. dir /b生效了,沒有輸出指令.

      • 最終版本

        @echo off
        dir /b
        
        D:\money\battst>ait.bat
        ait.bat
        dd
        good
        
        D:\money\battst>
        

        最終版本,一條指令都沒有輸出. @就表示,echo off的影響從當前行開始.

    • 註釋

      • 說明

        • 當一個批處理文件太大,往往是需要註釋的.
      • 註釋方式

        • :: comment
        • rem comment
  • 變量

    • 來源

      • 兩類: 參數類型變量,自動生成. 普通變量,自己定義.
    • 參數變量

      • 編號

        • %0 %1 %2 %3 ... %9,最多9個.
        • 可以通過SHIFT提升上限.即起始下標+1,args[0] = args[shift_time + 0].
        • 和普通程序一樣.
      • 變量輸出

        @echo off
        dir /b
        echo %0
        echo %1
        echo %2
        
        D:\money\battst>ait.bat 3 2
        ait.bat
        dd
        good
        ait.bat
        3
        2
        

        0是文件名,1,2就是參數.

      • 編號大於參數

        @echo off
        dir /b
        echo %0
        echo %1
        echo %2
        
        D:\money\battst>ait.bat 3
        ait.bat
        dd
        good
        ait.bat
        3
        ECHO 處於關閉狀態。
        

        因爲參數只有一個,echo %2的實際是echo ,提示錯誤.

      • 提升上限.

        ``cmd @echo off echo %0 echo %1 echo %10% shift echo %1 shift echo %1 shift echo %1 shift echo %1

        
        ```shell
        D:\money\battst>ait.bat 99 88 77 66 55 44 33 22 11 46
        ait.bat
        99
        990
        88
        77
        66
        55
        

        shift一次,0-9指向的位置就+1.

    • set定義變量

      • 說明

        • set定義變量.
        • 默認定義字符型,加選項可以定義數字型.
        • 即加選項對後面的字符串進行不同的解析處理.
        • (會棧的也可以自己實現這種)
      • 字符定義和數字

        @echo off
        set aaa=1
        set /a bbb=%aaa% + %aaa%
        echo %aaa% %bbb%
        
        D:\money\battst>ait.bat
        1 2
        

        /a 則將後面替換後的的字符串進行算術解析. (怎麼解析沒有研究過.) aaa就是字符串,但是bbb的結果是字符串按照算術解析的方式得到的結果。

        字符串方式也可以定義數字,但是運算就需要用set /a的方式.
    • 作用域

      • 說明

        • 有局部變量和全局變量.setlocal之後,endlocal,exit,eof之前定義的都是局部變量,退出範圍就恢復之前的值.
        • bat中的變量影響當前cmd,執行完了之後還在.
      • 案例

        @echo off
        set aaa=1
        setlocal enabledelayedexpansion
        set aaa=2
        echo %aaa%
        endlocal
        echo %aaa%
        
        

        注意aaa之前是1,局部輸出2,endlocal之後恢復.

        D:\money\battst>ait.bat
        2
        1
        
      • 退出後無效

        這裏改成ccc是因爲aaa執行後在環境變量中已經有定義.set | find "aaa" 可查看.
        @echo off
        setlocal enabledelayedexpansion
        set ccc=2
        echo %ccc%
        endlocal
        echo %ccc%
        
        
        D:\money\battst>ait.bat
        2
        ECHO 處於關閉狀態。
        
        • 之前演示的是定義後恢復值,這裏演示退出後未定義.
    • 環境變量

      • set查看已經定義的.和具體值.訪問和普通變量一樣.
  • 字符串

    • 說明

      • 全都是字符串.
      • set /a xxx = xxx + xxx的時候才進行算術運算,其他都是字符串操作.
    • 定義

      • 變量名和等號之間不能有空格.
      表達式 結果
      var = value var=之間有空格不行
      var= value 沒有空格,行.
    • 字符串和數字

      @echo off
      set sss=2
      set /a bbb=%sss% * 5 + 1000
      echo %bbb%
      set ccc=%bbb% + 10
      echo %ccc%
      set /a ddd=%ccc%
      echo %ddd%
      echo %ddd:~2%
      
      D:\money\battst>ait.bat
      1010
      1010 + 10
      1020
      20
      
    • 值爲空判斷

      @echo off
      set sss= 
      if "%sss%" == "" (echo empty) else (echo not empty)
      set sss=
      if "%sss%" == "" (echo empty) else (echo not empty)
      
      D:\money\battst>ait.bat
      not empty
      empty
      
      第一個有個空格,第二個是真的空.
    • 子串

      @echo off
      set str=cool
      echo %str:~1%
      
      
      D:\money\battst>ait.bat
      ool
      
      • 子串格式說明

        功能 案例
        %str:~start,len% start起始位置,len長度. %str:~1,1% => o
        %str:~start% start起始位置,這個位置以後的所有. %str:~1% => ool
        %str:~start,-pos% start起始位置,-pos標示倒數第幾個爲止,不包含. %str:~1,-1% => oo
        %str:~-pos% -pos,從倒數第pos個起,包含. %str:~-1% => l
        %str:~-pos,len% -pos開始,長度爲len的子串 %str:~-3,2% => oo
        %str:~-pos,-end -pos開始,到倒數第end的一個,end不包含. %str:~-3,-1% => oo
    • 替換

      @echo off
      set aaa=what the fuck
      echo %aaa%
      echo %aaa:fuck=f*k%
      
      D:\money\battst>ait.bat
      what the fuck
      what the f*k
      
    • 字符串長度

      rem @echo off
      set str=cool
      call :func_strlen str retlen
      echo %retlen%
      pause
      exit /b
      
      :: 函數定義
      
      :func_strlen
      setlocal enabledelayedexpansion
      :strLen_Loop
      if not "!%1:~%len%!" == "" set /a len+=1 & goto :strLen_Loop
      (endlocal & set %2=%len%)
      goto :eof
      
      

      bat沒有求長度的函數,使用循環截取子串判斷是否爲字符串末尾. :func_strlen自定義函數定義. :srLen_Loop循環. :func_strlen函數定義. endlocal臨時變量末尾 set %2=%len%,給%2的變量名賦值.所以retlen有值. goto :eof返回,參考鏈接https://stackoverflow.com/questions/37515901/where-does-goto-eof-return-to.call :label會模擬創建一個新的bat文件再執行腳本,goto :eof就是退出文件,而這裏是退出模擬文件,即返回了之前調用位置. exit /b不退出就會死循環,執行下面的函數並一直執行.及無限的調用函數退出.

      D:\money\battst>ait.bat
      
      D:\money\battst>rem @echo off
      
      D:\money\battst>set str=cool
      
      D:\money\battst>call :func_strlen str retlen
      
      D:\money\battst>setlocal enabledelayedexpansion
      
      D:\money\battst>if not "!str:~!" == "" set /a len+=1   & goto :strLen_Loop
      
      D:\money\battst>if not "!str:~1!" == "" set /a len+=1   & goto :strLen_Loop
      
      D:\money\battst>if not "!str:~2!" == "" set /a len+=1   & goto :strLen_Loop
      
      D:\money\battst>if not "!str:~3!" == "" set /a len+=1   & goto :strLen_Loop
      
      D:\money\battst>if not "!str:~4!" == "" set /a len+=1   & goto :strLen_Loop
      
      D:\money\battst>(endlocal   & set retlen=4 )
      
      D:\money\battst>goto :eof
      
      D:\money\battst>echo 4
      4
      
      D:\money\battst>pause
      請按任意鍵繼續. . .
      
      D:\money\battst>exit /b
      
  • 數組

    • 說明

      • 其實也是字符串,不過是字符串拼接.
      • 可以用set查看.
      • 不過多了這個編程概念,下標一般從0開始
    • 定義

      @echo off
      for /l %%i in (1,1,10) do set sss[%%i]=%%i
      set | find "sss"
      
      D:\money\battst>ait.bat
      sss[10]=10
      sss[1]=1
      sss[2]=2
      sss[3]=3
      sss[4]=4
      sss[5]=5
      sss[6]=6
      sss[7]=7
      sss[8]=8
      sss[9]=9
      
    • 遍歷

      @echo off
      for /l %%i in (1,1,10) do set sss[%%i]=%%i
      set | find "sss"
      setlocal enabledelayedexpansion
      for /l %%i in (1,1,10) do echo !sss[%%i]!
      

      setlocal enabledelayedexpansion使用了延遲擴展,延遲擴展用!來表示.%在第一次的時候會擴展,而!則在第二次的時候進行擴展,

      D:\money\battst>ait.bat
      ssss=abcdefg
      sss[10]=10
      sss[1]=1
      sss[2]=2
      sss[3]=3
      sss[4]=4
      sss[5]=5
      sss[6]=6
      sss[7]=7
      sss[8]=8
      sss[9]=9
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
    • 長度

      數組需要從0定義,否則長度不準確.

      判斷類似字符串,但是因爲是變量,所以可以用關鍵字define.

    • 長度案例

      @echo off
      for /l %%i in (1,1,10) do set sss[%%i]=%%i
      setlocal enabledelayedexpansion
      for /l %%i in (1,1,100) do if defined sss[%%i] (set /a len+=1) else (goto :out)
      :out
      echo %len%
      
      
      D:\money\battst>ait.bat
      10
      

      **起始下表不是從0開始,其實不標準.

  • 決策

    • 解析

      • 按行解析,如果要多行,就要在行末尾表示行未結束.
      • 如何處理數字和字符串

        • 主要根據運算符有關.
        • 運算符決定了符號兩邊的解析方式.
      • if

        • 支持if,if else, if if等.
      • 變量操作

        • defined判斷是否定義.
      • ==

        • 等於
      • errorlevel n

        • 上一次指令的退出嘛是否是n.n是自己的數字.
      • %errorlevel%

        • 上一條指令的返回值.
        • call可以一起用call other.cmd
      • goto

        • 跳轉到指定的位置.
        • 注意call裏面的goto.見前面.
    • 語法解析

      @echo off
      if 1 == 1 (echo nice) else (echo good)
      
      if 1 == 1 (echo nice) else (
      echo good)
      
      if 1 == 1 (
      echo nice
      ) else (
      echo good
      )
      
      if 1 == 1 (echo nice
      ) else (
      echo good)
      
      ::else
      ::(echo good)
      
      需要在行末尾表示行結束,else後啥都沒有就是錯誤的.
  • 運算符

    • 使用場景

      • 一般用於條件判斷。
      • 不多也可以用於其他場景
    • 總覽

      分類 說明
      數學運算 + - * / %,不支持浮點
      關係運算 >gtr;>=geq;==equ;<lss;<=leq;使用英文縮寫,而不是>,<之類.==比較特殊. a < A,a < b,110 > 12.和字符值無關.數字按數字規則,字符串按字符串.
      邏輯運算 and or not,可以用於拼接bool表達式,即if.
      賦值運算符 += -= *= /= %=,算術運算.
      位運算 `&
      重定向 `> >> < 2> 1>
  • 退出碼

    • %errorlevel%
  • 函數定義

    • 函數要素

      要素 說明
      聲明 :function_name,和goto的位置標籤一樣.
      定義 若干個指令
      返回值 exit /b code返回
      獲取返回值 %errorlevel%獲取執行函數的返回值.
      參數賦值 endlocal & set %2=%var1%
      參數 call :func_name arg1 arg2 arg3
      獲取參數 %1,%~1
    • exit /b

      • 僅僅退出批處理腳本,而不是退出cmd.exe
    • call :function_name

      • 調用函數,可以看成是在個新的cmd裏面執行.
      • 但是變量會共享,所以一般會添加setlocal,endlocal.
      • 而且function裏面可以定義:label.
      • 案例

        ::@echo off
        
        call :func_test 200 retlen
        echo %retlen%
        
        pause
        exit /b 2
        
        :func_test
        setlocal enabledelayedexpansion
        
        set /a dd=%1
        :while
        if %dd% gtr 0 (
            set /a dd/=10
            set /a cnt+=1
            goto :while
        )
        endlocal  & set %2=%cnt%
        goto :eof
        
        
        • 功能是判斷一個數佔幾位.
        • endlocal & 是一句,會立即解析.
    • 局部變量

      • 在函數中,局部變量是很重要的.
      • 可以避免與外界變量衝突
    • 遞歸

      ::@echo off
      
      call :func_test 200
      echo %errorlevel%
      
      pause
      exit /b 2
      
      :func_test
      
      setlocal enabledelayedexpansion
      if %1% gtr 0 (
          set /a tmp=%1%/10
          call :func_test %tmp%
          set /a ret=!errorlevel!+1
          exit /b !ret!
      )
      
      
      • 和上面一樣的功能,一樣的結果.
      • 這裏有enabledelayedexpansion才能執行成功,因爲是執行的時候才擴張.
  • 循環

    • 常見格式

      • for {%% | %}<variable> in (<set>) do <command> [<commandlineoptions>]
      • %%var%var的方式聲明變量.
      • in固定格式。
      • (<set>),() 括號裏面是集合,集合有很多種.
      • command循環體.
      • for in do固定格式.
    • set

      • 範圍

        /l : loop,start,step,end.end包含.
        @echo off
        for /l %%i in (1,2,10) do ( echo %%i )
        
        D:\money\battst>ait.bat
        1
        3
        5
        7
        9
        
      • 路徑/d : directory

        @echo off
        for /d %%i in (*) do ( echo %%i )
        
        D:\money\battst>ait.bat
        dd
        good
        
        路徑
        D:\money\battst>tree
        D:.
        ├─dd
        └─good
        
      • 文件/r :recursive

        遞歸查看
        @echo off
        for /r %%i in (*) do ( echo "%%i")
        
        D:\money\battst>ait.bat
        "D:\money\battst\ait.bat"
        "D:\money\battst\aitd.bat"
        "D:\money\battst\dynamic_sub.bat"
        "D:\money\battst\dd\1.txt"
        
        D:\money\battst>tree /f
        卷 有錢人的固態 的文件夾 PATH 列表
        卷序列號爲 DED3-62FD
        D:.
        │  ait.bat
        │  aitd.bat
        │  dynamic_sub.bat
        │
        ├─dd
        │      1.txt
        │
        └─good
        
    • 一般不用usebackq

      • 即在括號內用反括號當成是指令執行.
    • /f

      • 說明

        • 文件操作,按行讀取,相關的開關進行按行解析.
      • 開關說明

        字段 說明
        eol eol開頭的行忽略.
        skip n行忽略,前n行丟棄掉.
        delims 對一行數據進行拆分.默認分隔符是空格和tab.
        tokens 選擇由delims分隔後的n個子串數組中的若干個.*;s-e;1,3,5,7,即指定選取的下標,可以是枚舉,可以是區間,可以是*通配符.
        變量 tokens的時候,%%i則對應取到數據的下標1,%%j則對應2,%%k則對應3,一次類推.
        說明 都有默認值
      • 操作文件

        ,aa,bb,cc,dd,
        ,ee,ff,gg,hh,
        ,ii,jj,kk,ll,mm
        oo,pp,qq,rr,ss,tt
        
      • 文件查看

        @echo off
        for /f %%i in (aa.csv) do ( echo "%%i")
        
        D:\money\battst>ait.bat
        "aa,bb,cc,dd,"
        "ee,ff,gg,hh,"
        "ii,jj,kk,ll,mm"
        
      • eol;end of line

        @echo off
        for /f "eol=," %%i in (aa.csv) do ( echo "%%i" )
        
        D:\money\battst>ait.bat
        "oo,pp,qq,rr,ss,tt"
        
      • delims,tokens

        @echo off
        echo ------------------------------------
        for /f "delims=," %%i in (aa.csv) do ( echo "%%i")
        echo ------------------------------------
        for /f "delims=," %%i in (aa.csv) do ( echo "%%i" "%%j" "%%k" "%%l")
        echo ------------------------------------
        for /f "delims=, tokens=*" %%i in (aa.csv) do ( echo "%%i" "%%j" "%%k" "%%l")
        echo ------------------------------------
        for /f "delims=, tokens=1-3,4" %%i in (aa.csv) do ( echo "%%i" "%%j" "%%k" "%%l")
        echo ------------------------------------
        for /f "delims=, tokens=1-4" %%i in (aa.csv) do ( echo "%%i" "%%j" "%%k" "%%l")
        
        
        D:\money\battst>ait.bat
        "aa"
        "ee"
        "ii"
        "oo"
        ------------------------------------
        "aa" "%j" "%k" "%l"
        "ee" "%j" "%k" "%l"
        "ii" "%j" "%k" "%l"
        "oo" "%j" "%k" "%l"
        ------------------------------------
        "aa,bb,cc,dd," "%j" "%k" "%l"
        "ee,ff,gg,hh," "%j" "%k" "%l"
        "ii,jj,kk,ll,mm" "%j" "%k" "%l"
        "oo,pp,qq,rr,ss,tt" "%j" "%k" "%l"
        ------------------------------------
        "aa" "bb" "cc" "dd"
        "ee" "ff" "gg" "hh"
        "ii" "jj" "kk" "ll"
        "oo" "pp" "qq" "rr"
        ------------------------------------
        "aa" "bb" "cc" "dd"
        "ee" "ff" "gg" "hh"
        "ii" "jj" "kk" "ll"
        "oo" "pp" "qq" "rr"
        
      • 分析

        None    = [0] = s.split(",")[0]
        *       = [0] = ",".join(s.split(","))
        range   = [:] = s.split(",")
        
      • (set)

        類型 說明
        (filename) 字符串來自文件. 可以多個文件
        "str" 字符串來自給定字符串
        'cmd' 字符串來自指令輸出
  • 發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章