訪客留言簿

星期五, 1月 27, 2012

[linux] 利用文字終端機整理圖片 (1)

前言

純文字命令列好方便的呀!

本次目標

  1. 將檔名符合的圖片抓到單一資料夾內
  2. 大量轉換圖片格式並指定新檔名
  3. 快速打包複數資料夾成不同壓縮檔

基本觀念

  1. linux 的終端機是以 bash 這支程式為主,所以你要用的 shell 語言就叫 bash shell。(大概)

  2. bash 吃不到的東西就沒法交給指定程式處理。比如說 bash 預設是不會去抓「現在目錄中的隱藏檔」的,所以你用 ls 指令是列不出隱藏目錄的或檔案的,用 cp 指令也一樣複製不了那些東西。

  3. 你可以寫 shell script 檔案(副檔名為 sh 的純文字檔),來執行比較需要繁複判斷和使用者輸入資料的工作,但 shell script 裡的指令,跟你平時輸入到純文字終端機裡的是一樣的東西,只是有變數需要引用時,寫 shell script 檔案比較輕鬆。

將檔名符合的圖片抓到單一資料夾內

假設今天,我們用 Firefox,裝了 ScrapBook 跟 AutoSave,想要抓無名相簿的圖片的話,就會在我們的 ScrapBook 的 data 資料夾下,開出很多的資料夾來。不過要一個個打開來找想要的圖複製到別處,不是很麻煩嗎?

所以為了快速複製圖片,我們就必須先瞭解 bash 的萬用字元有哪些,還有我們要找的圖的共通特點有什麼。

假設我們要抓的圖片,都是數字 1 開頭,然後總共有 10 位數,格式是 JPEG 的話,就可以用「1?????????.jpg」來代表這些圖片。(可以先用 ls 指令測試)

在此假設你現在所在的目錄 /tmp,底下有一個 Firefox 的使用者設定檔資料夾名為 User,以及一個你想拿來放整理好的圖片的資料夾 GRAPH。這時,先把你的終端機,切換到 /tmp 底下,再輸入以下指令即可。(請不要連 /tmp$ 也輸入了)

/tmp$ cp User/ScrapBook/data/*/1?????????.jpg -f GRAPH/

大量轉換圖片格式並指定新檔名

假設你有一堆 BMP 圖,覺得太佔空間,想轉成 PNG 或 JPEG 圖,但直接用 convert 沒辦法保留原先的檔名時,就可以利用變數來讓程式自動填上正確檔名。

for f in *.bmp; do convert $f $f.png; done && rename 's/.bmp.png/.png/' *.png

上面這一行,其實是兩道指令。第一個是 convert 轉檔程式,第二個是 rename 重新命名。

然後這裡有利用「迴圈判斷式」中的 for...do...done 來處理不同檔名的檔案。f 是我給這 for 迴圈命名的變數名稱(可隨意改成其他英數字),$f 則是代表我要引用這變數。

迴圈裡面有個 in 是在指定迴圈的執行範圍,這裡是指定跑完全部的 bmp 就結束迴圈,也就是說,當有 01.bmp 和 02.bmp 兩個檔案時,第一次 bash 抓到 01.bmp,開始跑(do)一次轉檔,結束後(done)會再去跑 02.bmp,然後 bash 抓不到別的 bmp 時,就會結束這個迴圈。

(※用數學來說,就是函數 f(x)=a+1 時,假設 a 為 1-10 共十個數字,那就是計算十次;若假設 a 為 1 2 3 的話,就是計算三次。)

然後迴圈之中的工作,一定要記得在適當的地方加上分號「;」來斷開,才能再下達其他動作。比如說你可能會想 do 了 convert,就直接 do rename,這兩個 do 的動作,一定要用分號「;」隔開。(分號「;」要緊鄰前面的字,後面也要記得空一格,有時怎樣都跑不成功,就是因為多一格少一格的關係。)

而雙 and 符號「&&」,則是代表做完前一個指令,再接著做下一個指令。以這邊來說,用「&&」的話,就可以繼承前面的迴圈變數,繼續工作。跟寫在迴圈中不一樣的地方,只差在會跑一次迴圈就馬上做,或是迴圈全做完,才來做而已。

如果做完後,想順便清掉 bmp 圖,可以在上面的指令,加寫「&& rm *.bmp」,記得「&&」前要空一格。(如果寫進迴圈裡的話,一張張轉檔改名的同時,就會清掉,而不是全做完才清。)

rename 的用法改天有機會再談。這邊的 rename,主要是因為引用 f 變數,會讓檔名多出 .bmp,所以才要再修改一次的。

快速打包複數資料夾成不同壓縮檔

最後這節沒啥好說的。如果你有裝 7z 這程式的話,可以用下面的迴圈,幫你把不同名稱的資料夾,打包成不同名稱的壓縮檔。(7z 可以換成其他你喜歡的壓縮程式,壓縮格式和壓縮級別、是否加密也可以自己調整。)

for f in *; do 7z a "$f.7z" -mx=0 "$f"; done

這邊要記得用雙引號「"」包住檔名(即 $f.7z$f),不然檔名有空格時,程式會出錯。

希望 7z 加密的話,請加入「-p -mhe=on」這兩個功能,就會向你問密碼,然後加密檔名,讓人看不見壓縮檔裡面有啥了。

0 comments:

 

本站著作(不包含圖片、影音以及回應留言)係採用 Creative Commons 姓名標示-非商業性-相同方式分享 2.5 台灣 (中華民國) 授權條款授權