文章目錄
一、dos歷史學習筆記(後期整合到這裏,我想能學到這裏的應該不多了,嘿嘿,加油)
這個是我所以的dos學習筆記,希望對感興趣的你有所幫助,如有錯誤,還望不吝賜教。如果對你有幫助,希望給我點個贊哈,Thanks♪(・ω・)ノ
學習主要還是靠堅持,如果真的覺得學一個知識,就堅持下去;三天打魚倆天曬網,真的不如躺着歇,刷刷劇,或者玩倆局遊戲。。。
window的dos命令學習筆記 八— bat文件打包成exe程序(實現腳本加密)
二、函數:
這裏我補充一個dos函數的格式和用法,不然後面的可能用到函數的地方理解不了,而且函數也是常用的。
爲了學習這個函數,我這裏找了倆個有關dos的函數博客,大家學習可以參考參考。
如果看了人家的博客,覺得對你有幫助,記得給人家點個贊,也算是對原創作者的一個鼓勵(我已經偷偷點讚了,比較看懂了一些dos函數的知識)。
博客一
博客二
0、一些特殊字符的轉義:
因爲下面的的內容涉及的一些內容,如果這裏不說一下一些轉義字符,會耽誤太多時間,我也是自己耽誤時間之後,搜索了許久找到一個博客總結的還不錯,博客地址,因爲下面的內容中有個%%0
我沒有看懂,但是結果就是輸出%0
,意思是倆個%%
轉義成一個%
,所以搜索許久找到。
我這裏手動把作者的整理的轉義敲過吧。
期望得到的字符 | 轉義前字符(代碼中的字符) |
---|---|
% | %% |
^ | ^^ |
& | ^& |
> | ^> |
| |
^| |
’ | ^’ |
` | ^` |
, |
^, |
; | ^; |
= | ^= |
( | ^( |
) | ^) |
! | ^^! |
\ |
^\ |
[ | ^[ |
] | ^] |
" | ^" |
通過測試,我發先什麼作者的有些問題,我把他們更改爲正確的,最後突然發現,除了%%
轉義成%
,其他都是前加上^
進行轉義。
我的測試代碼:
@echo off
set aa=C:\Windows\PPP\a.btx
call :deal aaa %aa% "c c" ddd eee
pause>nul
exit
:deal
echo %%0 =
timeout 1
echo ^^ =
timeout 1
echo ^& =
timeout 1
::echo ^<</code> =
timeout 1
echo ^> =
timeout 1
echo ^| =
timeout 1
echo ^' =
timeout 1
echo ^` =
timeout 1
echo ^, =
timeout 1
echo ^; =
timeout 1
echo ^= =
timeout 1
echo ^( =
timeout 1
echo ^) =
timeout 1
echo ^! =
timeout 1
echo 原先的:\\ =
echo ^\ =
timeout 1
echo 原先的:\[ =
echo ^[ =
timeout 1
echo 原先的:\] =
echo ^] =
timeout 1
echo 原先的:\" =
echo ^" =
timeout 1
goto:eof
注意點:
rem
和 ::
(英文雙引號)都註釋的作用
這幾個錯誤的地方(可能之前能用吧,不過現在是需要^
進行轉義):
1、dos函數的結構
這裏我只寫入一些主要內容吧,想詳細看的去看看上面倆篇博客。
:myDosFunc - 函數的開始,用一個標籤標識(可以理解爲函數名)
函數體(寫入函數邏輯)
GOTO:EOF 函數結束,固定,可以使用小寫
2、批處理文件中執行函數:
call :myDosFunc 其實call是執行批處理文件的,myDosFunc可以理解爲函數名。
3、傳遞參數:
這個我是在作者中的代碼修改的。註釋我寫在每一行了,這裏不過多介紹了。
@echo off
:: 空格分隔
call:myDosFunc 100 YeePEE
:: 空格分隔
call:myDosFunc 100 "for me"
:: 逗號分隔
call:myDosFunc 100,"for me"
:: 逗號+空格分隔
call:myDosFunc 100,for me
:: tab鍵分隔
call:myDosFunc 100 for me
:: 空格鍵+tab鍵分隔
call:myDosFunc 100 for me
echo.&pause&goto:eof
:myDosFunc
echo 參數1: %1 參數2: %2 參數3: %3 參數4: %4
goto:eof
運行結果:
小結:
總傳參的結果可以看到,call執行批處理文件或者函數的時候,可以使用逗號
,空格
,tab鍵
三種分開傳遞,而且可以同時使用。
4、全局變量和局部變量的區別:
函數中,不做任何操作,如果直接使用外面全局的變量名,進行賦值等操作,會改變全局變量的最終結果。
@echo off
set aa=123
call :fun1 %aa%
echo %aa%
pause
:fun1
echo 函數名:%0
echo 參數1:%1
set aa=456
goto:eof
運行結果,可以看出,外面的全局變量aa在函數中被更改了。
函數的局部變量:
函數的局部變量
局部變量放在SETLOCAL與ENDLOCAL之間定義。
SETLOCAL可以很好的保護函數內與外面的變量不會衝突。即:
setlocal
set aa=456
endlocal
比如,我上面的代碼進行更改:
@echo off
set aa=123
call :fun1 %aa%
echo %aa%
pause
:fun1
echo 函數名:%0
echo 參數1:%1
setlocal
set aa=456
endlocal
goto:eof
執行結果:
從結果來看,發現局部變量的定義已經無法影響外部的全局變量了。
5、函數的返回值:
這裏我直接引用原作者的內容了。
1、直接函數內部改變全局變量
其實這個,我們前面有個測試局部變量的時候已經用到了。可以直接在函數內部修改全局變量。
修改完善的代碼:
set "var1=some hopefully not important string"
echo var1 之前是: %var1%
call:myGetFunc
echo var1 之後是 : %var1%
:myGetFunc
set "var1=DosTips"
goto:eof
運行結果:
2、我感覺作者的第二個和第一個一樣吧
我感覺作者的第二個和第一個一樣吧,只不過把外部的全局變量的名稱作爲參數傳入函數內部,在進行更改,和不傳入參數,直接修改變量名的是一樣的,下面是我根據作者的函數博客進行修改的。
@echo off
set "var1=CmdTips"
echo var1 before: %var1%
call:myGetFunc var1
::call:myGetFunc %var1%
echo var1 after : %var1%
pause
:myGetFunc
echo %1
echo %%1%
set "%1=DosTips"
goto:eof
運行結果:
三、字符串的一些操作
在批處理中,set的功能有點繁雜:設置變量、顯示環境變量的名及值、做算術運算、等待用戶的輸入、字符串截取、替換字符串,是我們常用的命令之一。
1、截取字符串
在字符串截取方面,新手因爲沒能注意到偏移量的問題,很容易提取到錯誤的字符串,因此,這裏,詳細解釋 set 截取字符的用法。
我們先來看一個例子:
set str=123456789
現在,我需要提取變量 str 中的第一個字符,那麼,該怎麼寫命令呢?
set var=%str:~1,1%
?我想,這很可能是很多粗懂set用法的新手們的第一反應,實際上,這條語句提取到的是字符"2",並不是我們想要的"1",也就是說,set var=%str:~1,1%
提取到的是字符串第二位上的字符,而不是第一位上的,這是什麼原因呢?
現在,我們可以把截取字符的命令用一條語句模式來表示,那就是:set var=%str:~偏移量,長度%
。(其實懂python的可以這樣理解,偏移量的數值就是對於字符串的下標,只不過下標是從0開始
,後面的長度就是指從下標開始要幾個字符)
下面我截圖一個代碼就懂了,可以自己敲一下
懂明白了。
到目前爲止,我們只談到了很簡單的截取操作,如果碰到比較複雜的提取需求,比如:提取第2個字符及其之後的所有字符、提取最後的3個字符、提取倒數第 2個及其之前的3個字符、提取除了最後4個字符的字符串……那又該怎麼辦呢?彆着急,set 命令在設計的時候就已經充分考慮到我們的複雜需求,只要對剛纔我們提到的字符截取語句稍做改動,就可以很輕鬆地完成任務。
我們知道,數字的正負可以用+-
符號來表示,同樣的,方向的正反也可以用±來標註。在 set 做字符截取的時候,引入了+-
符號來表示字符截取的方向:從左到右截取爲+,從右到左截取爲-,所以,
set var=%str:~1,4%
也可以寫成
set var=%str:~+1,+4%
只是在從右到左截取的時候,情況發生了一點變化,那就是:偏移量的起點以整個字符串最後一個字符的後一位來計算。現在,我們可以來回答上一段中提出的一些問題:
提取最後的3個字符:
set var=%str:~-3%
提取倒數第2個及其之前的3個字符:
set var=%str:~-5,4%
提取除了最後4個字符的字符串:
set var=%str:~0,-4%
提取最後四位:
set var=%str:~-4,4%
在 set var=%str:~偏移量,長度%
這樣的語句中,如果沒有逗號及其之後的長度,就表示截取偏移量位置上及其之後的所有字符;如果長度的值爲負數,則表示拋棄最後幾個字符。
假設 set str=123456789
現在,我們可以對任意位置上的字符做提取工作了(假設 set str=123456789):
① 提取1
set str=123456789
set var=%str:~0,1% 或 set var=%str:~0,-8% 或 set var=%str:~-9,1%
② 提取2
set str=123456789
set var=%str:~1,1% 或 set var=%str:~1,-7% 或 set var=%str:~-8,1%
③ 提取9
set str=123456789
set var=%str:~8,1% 或 set var=%str:~8% 或 set var=%str:~-1,1% 或 set var=%str:~-1%
④ 提取123
set str=123456789
set var=%str:~0,3% 或 set var=%str:~0,-6% 或 set var=%str:~-9,3%
⑤ 提取234
set str=123456789
set var=%str:~1,3% 或 set var=%str:~1,-5% 或 set var=%str:~-8,3%
⑥ 提取789
set str=123456789
set var=%str:~6,3% 或 set var=%str:~6% 或 set var=%str:~-3,3% 或 set var=%str:~-3%
總結:
最後,我們來總結一下字符截取的規律:
①、替換字符串格式
set str=123456789
set var=%str:~數值1,數值1%
說明:
- 截取字符串可以用
set var=%str:~數值1,數值2%
這樣的語句來實現; - 字符的截取是以
偏移量
(也可以理解爲下標
)來計算的,而不是以字符的絕對位置來計算; - 當
數值1
爲正數時,表示從左到右截取;當數值1
爲負數時,表示從右到左截取; - 當
數值2
爲正數時,表示要截取後字符串的長度;當爲負數時,表示要拋棄的最後幾個字符長度; - 當
數值2
及其之前的逗號不存在時,表示截取的是第(數值1+1)個字符及其之後的所有字符;
截取字符串可以說是字符串處理功能中最常用的一個子功能了,能夠實現截取字符串中的特定位置的一個或多個字符。
舉例說明其基本功能:
代碼:
@echo off
set ifo=abcdefghijklmnopqrstuvwxyz0123456789
echo 原字符串(第二行爲各字符的序號):
echo %ifo%
echo 123456789012345678901234567890123456
echo 截取前5個字符:
echo %ifo:~0,5%
echo 截取最後5個字符:
echo %ifo:~-5%
echo 截取第一個到倒數第6個字符:
echo %ifo:~0,-5%
echo 從第4個字符開始,截取5個字符:
echo %ifo:~3,5%
echo 從倒數第14個字符開始,截取5個字符:
echo %ifo:~-14,5%
pause
當然,上面的例子只是將字符串處理的基本功能展示出來了,還看不出字符串處理具體有什麼用處。下面這個例子是對時間進行處理。
@echo off
echo 當前時間是:%time% 即 %time:~0,2%點%time:~3,2%分%time:~6,2%秒%time:~9,2%釐秒
pause
執行效果:
2、替換字符串
替換字符串,即將某一字符串中的特定字符或字符串替換爲給定的字符串,這個比較簡單。
舉例說明其功能:
@echo off
set aa=偉大的中國!我爲你自豪!
echo 替換前:%aa%
echo 替換後:%aa:中國=中華人民共和國%
echo aa = %aa%
set "aa=%aa:中國=中華人民共和國%"
echo aa = %aa%
pause
單個步驟講解:
對於上面的例子有一點說明,對比兩個echo aa = %aa%
可以發現,如果要修改變量aa的內容的話,就需要將修改結果“%aa:中國=中華人民共和國%
”賦值給變量aa。上面的字符串截取也有着同樣的特點。
總結:
set aa=字符串的使用,字符串的剪切,字符串的替換。
set aa=%aa:字符串=str%
echo %aa%
有上面的代碼可以知道,字符串的替換就是把變量
(例子的指aa
),set aa=%aa:字符串=str%
中的字符串
,就是需要替換的字符串,後面的str
就行需要最後替換成功的字符串,返回的就是結果,如果aa
含有多個需要替換的,會全部被替換。
3、字符串合併:
其實,合併字符串就是將兩個字符串放在一起就可以了。這個看一下自己敲一遍就懂了。
舉例說明:
@echo off
set aa=偉大的中國!
set bb=我爲你自豪!
echo %aa%%bb%
echo aa=%aa%
echo bb=%bb%
set "aa=%aa%%bb%"
echo aa=%aa%
pause
執行結果,
同樣,如果要改變變量aa的內容的話,就需要將合併結果“%aa%%bb%”賦值給變量aa。
4、擴充字符串(其實就是獲取文件的磁盤、目錄、創建時間,文件名、後綴等信息)
“擴充”這個詞彙來自於微軟自己的翻譯,意思就是對錶示文件路徑的字符串進行特殊的處理,具體功能羅列如下:
這個吶,是for的幫助文檔裏面的,cmd中輸入 for /?
最後面即可看到。
另外,FOR 變量參照的替換已被增強。你現在可以使用下列
選項語法:
%~I - 刪除任何引號("),擴展 %I
%~fI - 將 %I 擴展到一個完全合格的路徑名
%~dI - 僅將 %I 擴展到一個驅動器號
%~pI - 僅將 %I 擴展到一個路徑
%~nI - 僅將 %I 擴展到一個文件名
%~xI - 僅將 %I 擴展到一個文件擴展名
%~sI - 擴展的路徑只含有短名
%~aI - 將 %I 擴展到文件的文件屬性
%~tI - 將 %I 擴展到文件的日期/時間
%~zI - 將 %I 擴展到文件的大小
%~$PATH:I - 查找列在路徑環境變量的目錄,並將 %I 擴展
到找到的第一個完全合格的名稱。如果環境變量名
未被定義,或者沒有找到文件,此組合鍵會擴展到
空字符串
可以組合修飾符來得到多重結果:
%~dpI - 僅將 %I 擴展到一個驅動器號和路徑
%~nxI - 僅將 %I 擴展到一個文件名和擴展名
%~fsI - 僅將 %I 擴展到一個帶有短名的完整路徑名
%~dp$PATH:I - 搜索列在路徑環境變量的目錄,並將 %I 擴展
到找到的第一個驅動器號和路徑。
%~ftzaI - 將 %I 擴展到類似輸出線路的 DIR
在以上例子中,%I 和 PATH 可用其他有效數值代替。%~ 語法
用一個有效的 FOR 變量名終止。選取類似 %I 的大寫變量名
比較易讀,而且避免與不分大小寫的組合鍵混淆。
昨天學習筆記的最後一個查詢文件名,就是其中的一個語法。獲取文件名就是這個%~nI - 僅將 %I 擴展到一個文件名
。
以上內容引用於for /?
幫助信息。其中的I代表變量I,不過需要說明的是,不是所有的變量都能夠進行擴充的,有兩個條件:
- 該字符串代表一個文件路徑;
- 變量要用%x來表示,x可取a-z A-Z 0-9共62個字符中的任意一個。舉例說明:
@echo off
echo 正在運行的這個批處理:
echo 完全路徑:%0
echo 去掉引號:%~0
echo 所在分區:%~d0
echo 所處路徑:%~p0
echo 文件名:%~n0
echo 擴展名:%~x0
echo 文件屬性:%~a0
echo 修改時間:%~t0
echo 文件大小:%~z0
pause
執行結果:
其中代碼中的%0
就是批處理傳入的參數,這個是第一個學習筆記的內容,%0
代表文件本身,後面的%1- %n
代表第1-n
個傳入的參數。
@echo off
set aa=C:\Windows\PPP\a.btx
call :deal aaa %aa% "c c" ddd eee
pause>nul
exit
:deal
echo %%0 = %0
echo %%1 = %1
echo %%2 = %2
echo %%3 = %3
echo %%4 = %4
echo %%5 = %5
其中,變量aa在之前是不可以擴充的,通過call命令並將aa作爲參數傳遞給子函數:deal
,將aa變量轉換成了變量%1,即符合%x格式,從而可以進行字符串擴充。
至於%x中x取a-z A-Z的形式,可以複習一下for語句,for語句裏面的變量就是用%x來表示的,因而可以直接進行擴充。
5、數值計算
批處理裏面的數值計算功能較弱,只能夠進行整型計算,忽略浮點數的小數部分;同時數值計算的範圍也受限於系統位數。
數值計算需要使用set
命令,具體格式爲“set /a expression
”。其中,expression
代表計算表達式,計算表達式跟C語言裏面的表達式基本上完全一致。set
支持的運算符也跟C語言裏面的一樣,只是沒有了増一減一。
set支持的運算符及優先級排序如下:
並以遞減的優先權順序支持下列操作:
() - 分組
! ~ - - 一元運算符
* / % - 算數運算符
+ - - 算數運算符
<< >> - 邏輯移位
& - 按位“與”
^ - 按位“異”
| - 按位“或”
= *= /= %= += -= - 賦值
&= ^= |= <<= >>=
, - 表達式分隔符
如果你使用任何邏輯或取餘操作符, 你需要將表達式字符串用引號擴起來。在表達式中的任何非數字字符串鍵作爲環境變量名稱,這些環境變量名稱的值已在使用前轉換成數字。如果指定了一個環境變量名稱,但未在當前環境中定義,那麼值將被定爲
零。這使你可以使用環境變量值做計算而不用鍵入那些 % 符號來得到它們的值。如果 SET /A 在命令腳本外的命令行執行的,那麼它顯示該表達式的最後值。該分配的操作符在分配的操作符
左邊需要一個環境變量名稱。除十六進制有 0x 前綴,八進制
有 0 前綴的,數字值爲十進位數字。因此,0x12 與 18 和 022
相同。請注意八進制公式可能很容易搞混: 08 和 09 是無效的數字,
因爲 8 和 9 不是有效的八進制位數。(& )
寫個簡單的循環10次:
@echo off
set a=0
:add
set /a a=%a%+1
echo %a%
if %a% leq 10 goto add
pause
四、總結set
今天又學了一些字符串的操作之後,發現dos的set命令真的很強大,目前學到的功能還不少。看來比我當前學到時認爲的還要重要的。
目前的功能:
- 設置變量:
set aa=123
- 執行表達式:
set /a 運算邏輯(加減乘除等操作)
- input接入輸入:
set /p b=請輸入內容
- 字符串截取(剪切):詳情看面的截取總結吧。
set str=123456789
set var=%str:~數值1,數值1%
- 字符串合併(其實這個就是字符串拼接,和功能1和變量傳遞一樣。)
目前我學的的關於set就這麼多了,不知道後續還會不會給我驚喜。