原文: 寫個批處理腳本來幫忙幹活--周遊檔案夾&字元串處理 這次打算寫幾篇關于腳本方面的部落格,主要是記錄一下 Gradle 腳本和批處理腳本的一些寫法,友善後續查閱。
前言
平常開發過程中,一些較為重複的手工性工作,如果能讓腳本來幫忙處理,自然是最好的,剛好之前有些工作有點過于重複且都是手工性去完成,是以就想着能否寫個腳本來處理。
因為我還是用的 windows 開發,是以最開始想到的就是批處理腳本,但寫完後發現,重複性工作是可以交給腳本去處理了,但每次要執行這個腳本檔案還得打開腳本所在的檔案夾找到腳本點選去執行。
emmm,因為我是開發 Android 的,電腦開機時 Android Stuido 就沒關閉過,然後又想到 Gradle 的腳本可以直接通過 AS 來點選執行,這樣一來,執行腳本,也就是敲代碼過程中随手一個快捷鍵就搞定,簡單、友善。
是以,這篇就稍微來記錄下批處理腳本和 Gradle 腳本的一些寫法,很基礎簡單,因為我的需求就是執行 java 指令來對某個檔案夾下的 apk 檔案分别進行簽名,而後輸出新的命名方式的 apk 檔案。
是以,腳本涉及到的操作也就隻是檔案夾的周遊、字元串的處理、指令的執行這幾個方面而已,後續有新接觸再慢慢補充。
批處理腳本
1. 周遊指定檔案夾下的檔案
1.1 指令解釋
指令:
for [參數] %%變量名 in (比對符) do (執行的指令)
切記:每個指令之間必須以空格隔開,in 與 ( 之間有空格,do 與 ( 間也有空格,否則指令會無法成功執行
ps:本節隻講用批處理腳本執行 for 指令周遊檔案夾的場景,是以以下分析每個指令意義時,不介紹其他含義
[]:表示此項指令為可選
[參數]:參數取值一共有四種:
/d, /r, /l, /f
,加上無參數,是以一共五種場景
- 無參:周遊目前路徑的檔案夾下的檔案,但也可在
中指定路徑(比對符)
- /d:周遊目前路徑的檔案夾下的檔案夾,但也可在
(比對符)
- /r [路徑]:深度周遊指定路徑下的所有檔案,子目錄中的檔案也會被周遊到,如果沒指定路徑,預設目前路徑
- /l :當使用參數 /l 時,需結合
一起使用,此時(比對符)
括号内部的用法規則為:()
,此時的 for 指令作用等同于 java 語言中的 for 語句(start, step, end)
- /f :用于解析檔案中的内容,本節不做介紹
%%變量名:作用類似于
for(int i = 0; ; )
中的
int i = 0
,有些差別點的就是,批處理的 for 循環周遊每一個子項時,
%%變量名
<=> 每個子項,即
&&變量名
已經是指向具體的每個子項了
(比對符):在 in 指令之後 () 括号裡的内容可表示為通配符,用于按照指定的規則過濾檔案夾下的檔案,如 (*.txt) 表示周遊檔案夾内所有以 .txt 結尾的檔案
(執行的指令):前面的指令就可以取到檔案夾内指定的每個子項了,那麼接下去要對每個子項如何操作,就在這裡寫,類似于 java 的 for 指令後的 {} 大括号的作用
1.2 使用示例
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuMmZ4cTZ4gjZyUmZ4AjY3AjN0kDM4Q2MldzMzATMjljNfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
以下示例基于上圖中的檔案路徑,批處理腳本為 test.bat
- 無參:
for %%i in (*) do ( echo %%i )
效果:周遊目前目錄下的所有檔案
- 無參指定路徑:
for %%i in (c:\softwares\VisualBat\*.url) do ( echo %%i )
效果:周遊在
(比對符)
中指定路徑下的以 .url 結尾的檔案
- 帶參數 /d:
for /d %%i in (*) do ( echo %%i )
效果:周遊目前目錄下所有的檔案夾
- 帶參數 /d 指定路徑:
for /d %%i in (c:\softwares\VisualBat\*) do ( echo %%i )
效果:周遊指定目錄下的所有檔案夾,%%i 指向每個子檔案夾的絕對路徑
- 帶參數 /r :
for /r %%i in (*.url) do ( echo %%i )
效果:深度周遊目前路徑下所有以 .url 結尾的檔案,因為是深度周遊,是以 %%i 指向檔案的絕對路徑
- 帶參數 /r 指定路徑:
for /r c:\softwares\VisualBat\ %%i in (*.url) do ( echo %%i )
效果:同上圖
- 帶參數 /l :
for /l %%i in (1, 1, 5) do ( echo %%i )
效果:等效于 java 中的
for (int i = 1; i <= 5; i++)
語句,起始值,遞增或遞減,終止值都可自行設定
- 帶參數 /d /r:
for /d /r %%i in (*) do ( echo %%i )
效果:參數可結合使用,/d 表示周遊檔案夾,/r 表示深度周遊,是以以上指令作用為深度周遊目前目錄下的所有檔案夾,包括子目錄中的檔案夾
2. 臨時變量的使用
2.1 變量的基本用法
set key=value
切記:
key=value
三者之間絕對不能出現空格,不能為了像遵守 java 風格擅自給添加上空格,這與 java 的
int a = 1
聲明變量不同,切記
變量使用:%key%
示例:
@echo off
set name=dasuAndroidTv
echo %name%
效果:name 可當做臨時變量使用,使用時需用 %% 将變量名括起來使用
局限:不允許在 for 指令中類似上步中聲明變量并直接使用,如下:
@echo off
for /l %%i in (0,1,5) do (
set name=dasuAndroidTv
echo %name%
)
效果:在 for 指令中聲明臨時變量,并直接通過 %key% 方式使用時會出現上圖中的錯誤:ECHO 處于關閉狀态,但如果
set key=value
臨時變量的聲明是放在 for 指令外部,for 指令内部隻是使用的話,是可以的,如下:
@echo off
set name=dasuAndroidTv
for /l %%i in (0,1,5) do (
echo %name%
)
效果:在 for 指令外部聲明臨時變量,for 指令内部隻是使用,這種方式是允許的
2.2 變量在 for 指令中的用法
提問:那麼如果要在 for 指令中才聲明臨時變量,并使用的話,該如何做?
for 指令中臨時變量的使用:
- 需啟用變量延遲功能,指令:
setlocal enabledelayedexpansion
- for 指令中的臨時變量使用時用
感漢号括起來的形式代替!key!
%key%
- 理由:不清楚,google 來的解決方案,感興趣想深入研究的自行搜尋
@echo off
setlocal enabledelayedexpansion
set name=dasu
for /l %%i in (0, 1, 5) do (
set name=dasuAndroidTv
echo !name!
echo %name%
)
效果:說得白一點,在 for 指令中通過 %name% 方式使用的臨時變量,取的 name 這個臨時變量的值會一直是它在 for 指令外指派的内容,即使在 for 指令中通過 set 指令對這個變量又重新指派,也不會生效。
那麼,如果需要在 for 指令中通過 set 指令指派後的臨時變量能夠馬上拿來使用,需要兩個步驟,一在檔案開頭啟用變量延遲功能,指令:
setlocal enabledelayedexpansion
,二在 for 指令中通過
!name!
方式來使用臨時變量。
3. 字元串處理
3.1 截取
%key:~[start,num]%
解釋:當
%key%
中出現了
:~
,則表示要對 key 指向的這個字元串做截取操作,截取操作支援以下幾種形式:
- 截取指定位置開始的 n 個字元串:
,表示截取從下标 0 開始的之後 4 個字元%key:~0,4%
- 截取從指定位置開始的整個字元串:
,表示截取從下标為 4 開始的整個字元串%key:~4%
- 截取通過倒數方式指定開始位置的整個字元串:
,表示截取從倒數第 2 個字元開始的整個字元串%key:~-2%
- 截取通過倒數方式指定位置開始之後的 n 個字元串:
,表示截取從倒數第 4 個字元開始的 2 個字元%key:-4,2%
- 正數倒數方式相結合:
,表示截取從下标 2 開始到倒數第 2 個之間的字元串%key:~2,-2%
@echo off
rem (rem表示後面是注釋的内容,類似于 java //)原始字元串
set name=dasuAndroidTv
rem 注釋内容:表示截取從下标 0 開始的之後 4 個字元,輸出 dasu
echo %name:~0,4%
rem 注釋内容:表示截取從下标為 4 開始的整個字元串,輸出 AndroidTv
echo %name:~4%
rem 注釋内容:表示截取從倒數第 2 個字元開始的整個字元串,輸出 Tv
echo %name:~-2%
rem 注釋内容:表示截取從倒數第 4 個字元開始的 2 個字元,輸出 Android
echo %name:~4,-2%
rem 注釋内容:表示截取從下标 2 開始到倒數第 2 個之間的字元串,輸出 id
echo %name:~-4,2%
3.2 拼接
%key1%%key2%
解釋:将要拼接的那個字元串直接跟在被拼接的後面即可,不需要任何拼接操作符
@echo off
set name1=dasu
set name2=AndroidTv
echo %name1%%name2%
rem 這裡是注釋内容:輸出 dasuAndroidTv
3.3 替換
%key:被替換字元串=替換的字元串%
解釋:不解釋了,直接看示例,很容易明白
@echo off
set name=whoAndroidTv
echo %name:who=dasu%
rem 這裡是注釋内容:輸出 dasuAndroid
3.4 檔案特殊操作
如果是在 for 指令中周遊了某個檔案夾下的檔案,那麼此時可以通過一些特殊指令來擷取這個檔案的各種資訊,直接看示例:
@echo off
for %%i in (*.txt) do (
echo %%i
echo %%~fi
echo %%~di
echo %%~pi
echo %%~ni
echo %%~xi
echo %%~ti
echo %%~zi
)
解釋: 在通過 for 指令周遊檔案時,%%i 根據不同的 for 使用方式,内容也有所不同,具體見第 1 節。在上述這種用法下,%%i 指向了目前目錄下每個檔案名,完整的檔案名。
那麼,此時就可以通過一些特殊指令來取得檔案的相關資訊,比如:
- %%~fi:表示擷取該檔案的絕對路徑資訊
- %%~di:表示擷取該檔案所在的盤符
- %%~pi:表示擷取該檔案的路徑,不包含盤符的資訊
- %%~ni:表示擷取該檔案的檔案名,不包含擴充名資訊
- %%~xi:表示擷取該檔案的擴充名
- %%~ti:表示擷取該檔案的上次修改時間
- %%~zi:表示擷取該檔案的大小
4. 完整示例
最後,我們來個具體場景,将本篇所學的知識用上一遍,鞏固一下。
場景:周遊指定路徑目錄下的所有 apk 檔案,并通過一個 sign.jar 檔案,分别對每個 apk 檔案執行 java 指令來進行簽名工作,sign.jar 接收兩個參數,一個是需要簽名的 apk,另外一個為輸出的 apk,要求簽名後的 apk 命名方式為将原檔案名中的 unsign 替換成 google,并輸出在跟 apk 同一個目錄内即可。
apk 路徑:c:\users\suxq\desktop\outputs
sign.jar 路徑:c:\users\suxq\desktop
java 簽名指令示例(要求 sign.jar 和 apk 檔案都在同一路徑下,即可用如下指令):
java -jar sign.jar meizi_1_3_0_debug_unsign.apk meizi_1_3_0_debug_google.apk
批處理腳本代碼:
@echo off
setlocal enabledelayedexpansion
set sign=c:\users\suxq\desktop\sign.jar
set apkPath=c:\users\suxq\desktop\outputs\
for %%i in (%apkPath%*.apk) do (
set oldApk=%%~nxi
set outApk=!oldApk:unsign=google!
echo java -jar %sign% !oldApk! !outApk!
rem 這裡是注釋内容:由于 apk 檔案 和 sign.jar 檔案都是虛拟的,是以真正執行時會報錯,這裡就隻是将 java 整句指令輸出,從整句指令就可以确認是否會正确執行,如果這些檔案都是真的話。真的腳本應該将 echo 去掉
)
效果:完美~
首先,周遊指定目錄下的檔案達到了,而且可以對檔案名字元串進行處理,替換其中一些值,最後,可以根據指定位置的 sign.jar 檔案,通過 java 指令來執行簽名工作。
這個場景,剛好把我們今天學的關于批處理的周遊檔案夾操作、臨時變量使用、字元串的處理三者都包括在内,感興趣的也去試試看吧~
最近(2018-03)剛開通了公衆号,想激勵自己堅持寫作下去,初期主要分享原創的Android或Android-Tv方面的小知識,準備可能還有點不足,感興趣的可以先點一波關注,謝謝支援~~