OS Xはunixですから。
勉強会で出て来たのは、「感-5864.ai」という形式の名前を持つファイルを、冒頭の漢字1文字とハイフンまでを外した「5864.ai」という形式の名前にリネームしたい。たくさんあるのを一括処理したいという課題でした。
Terminal(shellはbash)でやれば簡単。
bashの「for name [ in word ] ; do list ; done」構文を使います。
sedでやってみる
まず、考えたのは手に馴染んでいるsedを使うやりかた。
for i in *.ai > do > cp $i `basename $i | gsed -e 's/^.-//'` > done
- basenameコマンドでファイル名をテキストとして取得:basename $i
- それをパイプを通じてsedに渡し、
- 先頭の一文字とそれに続くハイフン(^.-)を削除:s/^.-//
- ここまでの実行結果(`basename $i | gsed -e 's/^.-//'`)を新しいファイル名としてcpコマンドに渡す
ただし、漢字など多バイト文字はOS X付属のsedではうまく変換できないので、GNU sedが必要です。(bashの環境変数のうちLANGも、LANG=ja_JP.UTF-8とする必要があります)
perlをつかう
そこで、OS X付属のperlを使ってみました。こんな感じです。
for i in *.ai > do > cp $i `basename $i | perl -CIO -pe 'use utf8; s/^.-//;'` > done
【注】当初、「perl -pe 'use utf8; s/^.+-//;'」と書いていて、どうして「+」が必要なんだろうと不思議に思っていたのですが、エンコーディングの指定書式を旧式の「use encoding "utf8"」にすると文字数が思惑どおりになりました。しかし、その後、perlの起動オプション「-C」で出入力のエンコーディングを指定することを教わりました(man perlrun参照)。これでやっと現代的なコードになりました。みなさん、ありがとうございます。
bashだけでできる
そうこうしているうちに、bashだけでできるのに気付きました。こうです。
for i in *.ai > do > cp $i ${i/*-/} > done
変数を展開する際にその一部を書き換える機能をbash自体が持っているんです。
bashのmanpageでは、「Parameter Expansion」項の最後の方に載ってます。
${parameter/pattern/string}という構文です。
(今回はpatternの文字列を削除するのでstring文字列は空)
検索パターンの書き方にちょっと癖があるし、機能もsedやperlほどではないのですが、今回のような事例ならこれで充分役立ちます。
森さん、お世話になります。
返信削除use utf8;ではMacのファイルシステムで使われているUTF-8には聞かないが、use encodings "utf8"; では利いたということですね。
もっともメンテナーのダンさんによると、use encodingsは「黒歴史」であって使ってくれるなだそうです。
http://blog.livedoor.jp/dankogai/archives/51221731.html
起動オプションでのエンコード指定を教わったので、非推奨の書き方を改めました。
返信削除