TL;DR
# 查找並刪除鏡像(xxx代表查詢條件)
for /f "tokens=3" %i in ('docker images ^| findstr "xxx"') do @docker rmi %i
# 查找並刪除容器(xxx代表查詢條件)
for /f "tokens=1" %i in ('docker ps -a ^| findstr "xxx"') do @docker rm %i
如果對整個探索過程有興趣,可以繼續往下看。
docker用久了之後,可能會有一些冗餘的鏡像(和容器),一個一個去刪太麻煩了,就會需要批量刪除。而且,我想大家對在*NIX環境下的批量刪除已經很清楚了:
# 查找並刪除鏡像(xxx代表查詢條件)
docker rmi `docker images | grep xxx | awk '{print $3}'`
# 查找並刪除容器(xxx代表查詢條件)
docker rm `docker ps -a | grep xxx | awk '{print $1}'`
但是因爲我的開發環境是Windows,查了半天也只能查到在*NIX環境下(包括Mac)批量刪除docker容器和鏡像的方法。難道Windows不僅安裝docker麻煩,時不時有點奇怪的bug,甚至連批量刪除這點權利都沒有嗎?
當然,說完全查不到,也是一個誇張的說法;其實我還是看到了兩種方法的:
第一種是,把查詢結果寫入一個txt文件,然後讀txt文件的內容進行刪除。比如說,假如我要刪除所有的容器:
docker ps -a -q > 1.txt
for /f %a in (1.txt) do docker rm %a
但是這個太不優雅了,第一個是要分兩步去做,第二個是還會生成一個沒啥用的txt文件。
第二種是,手動去裝一下Windows版的awk,也就是gawk,然後就可以像在Linux裏一樣去弄了。當然他並沒有說接下來怎麼做,這一段是我腦補的:
# 查找並刪除鏡像(xxx代表查詢條件)
for /f %i in ('docker images ^| findstr "xxx" ^| awk "{print $3}"') do @docker rmi %i
# 查找並刪除容器(xxx代表查詢條件)
for /f %i in ('docker ps -a ^| findstr "xxx" ^| awk "{print $1}"') do @docker rm %i
雖然看上去還不錯,但是這個也不是很好。考慮到第一個是要裝一個額外的庫,並不具有遷移性,不是每個人都會裝這個庫;第二個是這個庫已經很老了,最新版也是08年發佈的,雖然現在還能兼容,萬一哪一天不兼容了呢?
如果非要槓的話,其實shell命令也有可能發生變化,原生實現也未必穩定;但是總比依賴於第三方的內容要更穩定一些。
好在功夫不負有心人,後來又查了一堆資料,摸索出一個辦法。其實也很簡單,因爲我們需要解決的核心問題其實就是兩個,第一個是怎麼在Windows下實現類似於awk的那種提取內容的效果,第二個是怎麼在Windows下實現類似於Linux中反引號和${}
這種把前一個命令的結果傳給後一個命令的效果。這兩點原生的for /f
都能做到:
# 查找並刪除鏡像(xxx代表查詢條件)
for /f "tokens=3" %i in ('docker images ^| findstr "xxx"') do @docker rmi %i
# 查找並刪除容器(xxx代表查詢條件)
for /f "tokens=1" %i in ('docker ps -a ^| findstr "xxx"') do @docker rm %i
整個邏輯相信大家都能看懂,因爲有for循環,甚至比Linux那個看起來還要直觀一點,但是可能需要稍微解釋一下這個tokens,文檔是這麼說的:
tokens=n The numbered items to read from each line (default = 1)
這個其實就類似於awk '{print $n}'
的效果,這樣第一個問題就解決了。而第二個問題,因爲是個循環,也就不是問題了。這個命令還有更多的用法,可以參考文檔。
所以……沒有所以。