2009/01/16

自動歸檔

先解釋一下我的 "自動歸檔" 是什麼意思。
我會不定時的,把硬碟中的檔案群,以檔案命名建目錄,再把同名的檔案全部都搬進去
這樣找起東西來比較輕鬆。

例:
[dmhy][exale][01][big5].avi
[dmhy][exale][02][big5].avi
[dmhy][exale][03][big5].avi
[dmhy][exale][04][big5].avi
[dmhy][exale][05][big5].avi

建一個 [dmhy][exale] 的目錄後,把以上檔案都搬進去

有時候 anime 太多,整理起來十分麻煩。
所以就興起寫一個 scripts 來做半自動歸檔的動作。

原本我是寫這樣:
F=`find . -type d -print`
for A in $F; do
if [ -d "$A" ]; then
mv "$A"*.* "$A"
else
mkdir -p "$A"
mv "$A"*.* "$A"
done

問題來了,當這支 scripts 遇到 "nut cgi bin" 時,會把它當成
nut
cgi
bin
三個字串
我嘗試過在 scripts 中把 $A 用 "$A" 包起來,但沒有作用
後來 garyzyg、CrBoy、psboy 指點,運用了 read ,解決字串會依空白拆行的問題

find . -type d -print |while read A; do
cp "$A"*.* "$A"
done
但是這樣會有錯誤訊息
cp: omitting directory `..'
原因 find 會列出 . 這層目錄,而且還多了 ./ 這個符號;於是我參考
http://blog.wu-boy.com/2009/01/13/712/
解決這個問題

重新寫成
find . -maxdepth 1 -mindepth 1 -type d -exec basename {} \; |while read A; do
cp "$A"*.* "$A"
done
就解決了我的問題 ^ ^

後記:
這樣的程式有個小缺點:
得先依檔案名稱建立目錄,才能讓 scripts 依目錄名稱去判斷檔案,再把檔案搬到目錄下

所以進階的寫法就是,以下面這個字串
[dmhy][exale][01][big5].avi

判斷
[dmhy][exale]

是否存在,若不存在,則建立
我要做的,就是把 [01] 開始的字串,全部拿掉,剩下的事就好辦了 :P

麻煩的是 sed 我不熟... @ @
正規式也不熟 ... 0rz

20 分鐘後的新增:
#!/bin/bash

# 依照檔案名稱先看看目錄在不在
# 不在->建目錄->搬檔案進去
# 在----------->搬檔案進去

# 先將目前檔案製成只有名稱,不含 "." 及副檔名的清單
find . -maxdepth 1 -mindepth 1 -type f -exec basename {} \; |sort|uniq >/tmp/filelist_raw
sed 's/\[[0-9][0-9]\]*.*$//g' /tmp/filelist_raw |sort|uniq > /tmp/filelist

# 再把檔案搬進去

cat /tmp/filelist |while read A; do
if [ -d "$A" ]; then
mv "$A"*.* "$A"
else
mkdir "$A"
mv "$A"*.* "$A"
fi
done

rm -f /tmp/filelist*

搞定~ ^ ^
shell scripts 實在是好物啊 (茶)

60 分鐘後續新增:
又想到一個進階的寫法:
  1. 列出所有檔案
  2. 以檔案名稱製作清單
  3. 檢查清單上的目錄是否存在
    1. 若存在,搬檔案進去
    2. 若不存在,依清單檢查檔案是否一個以上
      1. 一個以上:建目錄
      2. 一個:不作任何處理
  4. 建目錄後搬檔案進去
目前還需實作 3-2 的部份

沒有留言: