id:eel3:20110619:1308413539 の続き。
何やら妙なところで色々と苦労したものの、遂にMP3をmicroSDHCに書き込めるようになった。
なので早速フォルダごとMP3ファイルをコピー……とはいかない。このmicroSDHCはカーナビで使うのだ。カーナビ――そう、相手は組み込み機器。パソコンとは一味違う。
何を言いたいかというと、このカーナビはSDメモリに書き込まれた順でしかディレクトリやファイルを読み出せない。最上位の階層から書き込まれた順にディレクトリツリーを辿っていき、書き込まれた順にファイル情報を取得していく。
実際にはもう少し複雑……というかよく分からない挙動だ。というのも後からファイルやディレクトリを追加/削除したり名前を変更したりすると、そのファイル/ディレクトリはよく分からない順番で読み出される。
ファイルシステム周りは知識が無いのでよく分からないのだが、多分FATのテーブルなりエントリなりの情報を舐めた順番そのままに表示しているのだろう。
正直なところ「せめて名前順にソートしてくれないかなあ」と思わないでもないのだが*1、一方でカーナビではないが組み込みの仕事をしている身として気持ちは理解できる。メモリが足りないのか、応答速度の面で遅くなってしまうのか。どちらもありえそうだ。
発想を変えると、ディレクトリやファイルを書き込む順番を制御することで、自分が望む順番でカーナビにファイルを読み出させることが可能となる。これはこれで、うまく使えばメリットとなる。ただ後でディレクトリやファイルを追加する時に順番を調整しなおしたい場合には一旦ファイル等を削除する必要があるかもしれないが。
今回は、
- アーティスト名は名前順に並べる。
- アルバム名は発表順に並べる。
- 楽曲名はアルバムのトラック順に並べる。
といった条件を満たすような順番でディレクトリやファイルを書き込むことにした。
ところでSDメモリには複数のアーティストの複数のアルバムCDからリッピングしたMP3を書き込む。結構量が多いので、ディレクトリやファイルを指定した順番で書き込むにあたり、作業を自動化したい。
ディレクトリ一覧を作成する
Rhythmboxで取り込んだ音楽データは $HOME/ミュージック 以下に書き込まれる。手元の設定ではこのディレクトリ内に「アーティスト名/アルバム名」という命名規則でディレクトリが作成され、その中に各トラックの音楽データが「トラック番号 - 楽曲名.mp3」という感じの名前で書き込まれる。
SDメモリにデータを書き込む際は、
- $HOME/ミュージック 内のファイル・ディレクトリを、
- 名前は変更せず、
- 先に書いたルールに基づく順番で書き込む。
といったことを行うことになる。
まずは作成するディレクトリの一覧を取得してみた。
cd ~/ミュージック find . -type d | sort | sed -n 's/^\.\///p' > ../dirlist.txt
大体こんな感じの一覧が取得できる。
Cactus Cactus/Barely Contained - The Studio Sessions [Disc 1] Cactus/Barely Contained - The Studio Sessions [Disc 2] Creedence Clearwater Revival Creedence Clearwater Revival/Bayou Country Creedence Clearwater Revival/Creedence Clearwater Revival Creedence Clearwater Revival/Green River Creedence Clearwater Revival/Willy And The Poor Boys Foghat Foghat/Fool For The City
実際にSDメモリに書き込む内容の一部を抜粋。年齢を疑われる内容かもしれない :)
とりあえずこの一覧を、SDメモリに書き込んでほしい順番に並び替える。この一覧の場合、Creedence Clearwater Revivalのアルバムが微妙に発表順でないので修正する。
Cactus Cactus/Barely Contained - The Studio Sessions [Disc 1] Cactus/Barely Contained - The Studio Sessions [Disc 2] Creedence Clearwater Revival Creedence Clearwater Revival/Creedence Clearwater Revival Creedence Clearwater Revival/Bayou Country Creedence Clearwater Revival/Green River Creedence Clearwater Revival/Willy And The Poor Boys Foghat Foghat/Fool For The City
ディレクトリを書き込む順番はこれでOK。
ファイルの書き込み順はどうするのか? ファイル名は先頭にトラック番号が付いている。トラック番号はゼロパディングされている。少なくともあるディレクトリ直下のファイルに関しては、ワイルドカード * で処理すればトラック順に書き込まれるはずだ。
書き込み処理を行うスクリプトを生成するスクリプトを書く
元データとなりそうなディレクトリ一覧ファイル dirlist.txt が完成した。後はこのファイルを活用してファイルの書き込みを行うだけだ。
ここで頭の良い人ならPerlやRubyあたりでワンライナーでさくっと済ませるのだと思うし、普通の人はディレクトリ作成とファイルコピーをする使い捨てスクリプトをささっと拵えてしまうと思うのだが、私は頭の出来がイマイチな部類に入る人なので泥臭くこんなシェルスクリプトを書いてみた。
#!/bin/sh if [ $# -ne 3 ]; then echo "usage: `basename $0` <dirlist_file> <basedir_copy_from> <dir_copy_to>" 1>&2 exit 1 fi DIRLIST=$1 COPYFROM=`echo $2 | sed "s/\/$//"` COPYTO=`echo $3 | sed "s/\/$//"` sed 's/[][ ;&()|^<>?*$`"'"'"'{}#\\]/\\&/g' $DIRLIST | gawk ' BEGIN { print "#!/bin/sh\n" print "#rm -rf '"$COPYTO"'/*\n" } { copyto = "'"$COPYTO"'/" $0 print "mkdir " copyto if ($0 ~ /\//) { print "cp '"$COPYFROM"'/" $0 "/* " copyto } } '
sedとgawkの組み合わせ。もしかしたら、これも微妙に年齢を疑われる要素かも。
このスクリプト mkscript.sh を例えば以下のように実行すると、
./mkscript.sh dirlist.txt ./ミュージック/ /media/usbmem/ > copymp3.sh
こんなファイルが生成される。
#!/bin/sh #rm -rf /media/usbmem/* mkdir /media/usbmem/Cactus mkdir /media/usbmem/Cactus/Barely\ Contained\ -\ The\ Studio\ Sessions\ \[Disc\ 1\] cp ./ミュージック/Cactus/Barely\ Contained\ -\ The\ Studio\ Sessions\ \[Disc\ 1\]/* /media/usbmem/Cactus/Barely\ Contained\ -\ The\ Studio\ Sessions\ \[Disc\ 1\] mkdir /media/usbmem/Cactus/Barely\ Contained\ -\ The\ Studio\ Sessions\ \[Disc\ 2\] cp ./ミュージック/Cactus/Barely\ Contained\ -\ The\ Studio\ Sessions\ \[Disc\ 2\]/* /media/usbmem/Cactus/Barely\ Contained\ -\ The\ Studio\ Sessions\ \[Disc\ 2\] mkdir /media/usbmem/Creedence\ Clearwater\ Revival mkdir /media/usbmem/Creedence\ Clearwater\ Revival/Creedence\ Clearwater\ Revival cp ./ミュージック/Creedence\ Clearwater\ Revival/Creedence\ Clearwater\ Revival/* /media/usbmem/Creedence\ Clearwater\ Revival/Creedence\ Clearwater\ Revival mkdir /media/usbmem/Creedence\ Clearwater\ Revival/Bayou\ Country cp ./ミュージック/Creedence\ Clearwater\ Revival/Bayou\ Country/* /media/usbmem/Creedence\ Clearwater\ Revival/Bayou\ Country mkdir /media/usbmem/Creedence\ Clearwater\ Revival/Green\ River cp ./ミュージック/Creedence\ Clearwater\ Revival/Green\ River/* /media/usbmem/Creedence\ Clearwater\ Revival/Green\ River mkdir /media/usbmem/Creedence\ Clearwater\ Revival/Willy\ And\ The\ Poor\ Boys cp ./ミュージック/Creedence\ Clearwater\ Revival/Willy\ And\ The\ Poor\ Boys/* /media/usbmem/Creedence\ Clearwater\ Revival/Willy\ And\ The\ Poor\ Boys mkdir /media/usbmem/Foghat mkdir /media/usbmem/Foghat/Fool\ For\ The\ City cp ./ミュージック/Foghat/Fool\ For\ The\ City/* /media/usbmem/Foghat/Fool\ For\ The\ City
*1:名前順なら、名前の先頭に番号を付けることで表示順を制御できるので。