2012-04-19

カレント・ディレクトリー内の全てのファイルを新しい下位ディレクトリーに簡単に移動させる 〜 zsh 編

カレント・ディレクトリー内の全てのファイルを新しい下位ディレクトリーに簡単に移動させる 〜 dot dir を使って」というエントリーを書いた。すると、たつをさんが高速でブログの記事を書いていた。たつをさんは、こういうネタにすぐ飛びつき反応を見せてくれる。とても嬉しい。

曰く。

zsh だと「mv *(.) dir/」でOK

[を] ファイル名指定でよく使う zsh の便利な記法 より引用

説明もあった。

zsh では *(.) で通常ファイルだけを指定できる。これは知らなかった。具体的な操作はこうなるはず:

$ ls
a.txt b.txt c.txt
$ mkdir dir
$ mv *(.) dir

.dir を適切なディレクトリー名に変更する手間が省けて良いね。利用には .zshrc に setopt EXTENDED_GLOB を入れておく必要がある。

except glob を使う方法

*(.) を使う方法は、移動したいものが「ファイルだけ」の場合にのみ有効。そもそも、そういうやり方だから当たり前と言えば当たり前。問題は移動したいものに「ディレクトリーも」含まれる場合。例えばこんな感じ:

$ ls
a.html b.html c.html img/
$ mkdir dir
$ mv *(.) dir
$ ls
dir/ img/

ディレクトリーの移動までやってくれない。この場合、zsh の except globe が役に立つ。「*」から除外させたいファイル/ディレクトリーを指定するというもの。「[^除外したいファイル]*」という書式で書く。この場合、次の様になる:

$ ls
a.html b.html c.html img/
$ mkdir dir
$ mv [^dir]* dir
$ ls
dir/

dir ディレクトリー以外のファイル及びディレクトリーを全て dir ディレクトリーに mv する。

[^dir]* を使う方法は誤りでした。訂正記事を書きましたので、参照下さい。

あとがき

zsh は覚えることが沢山あるけど、覚えておくと一手間減らせるので便利。コマンド使いには凄くお勧め。ただし、システム管理者になって zsh のない環境でも動く shell script を書く様になると、どこまでが zsh 特有の便利機能か区別出来なくなって苦しむ。便利すぎる諸刃の剣。システム管理者にはバランスを取るのが難しい楽しい shell。

4 comments:

  1. ごめんなさい、追記しましたが、私の元記事は間違いでした。すみません...
    追記でも書きましたが、bashでは「mv !(dir) dir/」で、zshでは「mv *~dir dir/」でいけるみたいです。

    ReplyDelete
    Replies
    1. tyru さん、はじめまして。コメントありがとうございます。
      追記、拝読しました。zsh で「mv *~dir dir/」。ああ、そういうのもあったな... と思いました。

      ところで、「mv [^dir]* dir/」が間違いというのはどういうことでしょうか? 見た目、ちゃんと動いているように思います。このやり方だとダメなケースを教えて頂けますか。

      Delete
    2. それも追記分に書いてありますよー。

      > id:mattn: これ、正規表現のパターンだよね?ってことはa b c iってファイルがあったら[^dir]でiってファイル残るよね。

      Delete
    3. tyru さん、ご教授ありがとうございます。
      記事を書く時、ご提示の文は読んでいたのですが理解していませんでした。今、間違いと言われて、ちゃんと考えて、ようやく分かりました。私の失敗です。申し訳ないです。
      訂正記事を書きました。
      clmemo@aka: カレント・ディレクトリー内の全てのファイルを新しい下位ディレクトリーに簡単に移動させる 〜 zsh 編 その二

      Delete