Showing posts with label zsh. Show all posts
Showing posts with label zsh. Show all posts

2012-04-21

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

の続き。前の記事で、ディレクトリー「dir」以外の全てのファイル及びディレクトリーを指定する方法に「^dir]* と書いた。これは誤りだった。訂正記事を書く。

除外用の glob pattern

除外したいファイルがある場合、zsh では「*~除外したファイル名」という書式を使う。前エントリーからのお題をそのまま使うと、こうなる:

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

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

利用には .zshrc に setopt EXTENDED_GLOB を入れておく必要がある。

何故、[^dir]* は誤りか

まず、ぼくがこの記事を書いた時、参照記事既にこのやり方が誤りである、と記述があったことを強調しておきたい。ぼくは、「何が誤っているのか分からなくて」、このやり方を記事にしてしまった。全てぼくの不徳とする所。

さて、何故「^dir]* が誤りか。

このやり方は正規表現を使っている。[文字] は、括弧内に含まれる文字列のうち一文字を表す。つまり、[dir] ならば d か i か r という文字を表す。[^文字] はその否定。括弧内に含まれる文字以外を表す。従って、[^dir] ならば「d か i か r 以外の文字」を表す。ここに表てのファイル名を表す glob 表現「*」を続けると、[^dir]* の意味はこうなる。

先頭文字が d もしくは i もしくは r で始まらないファイル/ディレクトリーの全て

サンプル・コードでは先頭文字に d/i/r を持つファイルがなかった。また、サンプルに使ったディレクトリー名がたまたま「dir」で、この除外する条件を満たしてしまっていた。そのため、運良くプログラムが通ってしまった。サンプル・コードで、i や r から始まるファイル、もしくは foo といったディレクトリー名を使っていたら、このやり方が誤っているとすぐに分かったはず。

全く見事なヘマをやってしまった。お恥ずかしい。

ref

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。

2012-04-16

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

ファイルが多くなったので、ディレクトリーを作ってまとめちゃう。そんなことは良くある。そのやり方が目から鱗な方法が紹介されていたので、コピペ。

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

dir は適当なディレクトリー名をお付け下さい。

このやり方で何が目から鱗って、下から二行目のコマンド「mv * .dir」。カレント・ディレクトリーの全てのファイルを * で表しているわけだけど、それだと移動先であるディレクトリーも含まれてしまう。自分自身を自分の中に移動は出来ないのでエラーが出る。そこで、移動先のディレクトリーだけ排除して mv コマンドを実行したい。ここで、* (アスタリスク) が dot dir を含めないことを利用した。

一般に UNIX では、「.」で始まるファイル/ディレクトリーは隠しファイル/ディレクトリーになる。予め隠しディレクトリー「.dir」を mkdir で使っておき、mv コマンドで * (全てのファイル) をその .dir へ移動させる。.dir は隠しディレクトリーだから、「*」には含まれない。つまり、難しいことを考えなくても良い!!

作業が終わったら、隠しディレクトリーを適切なディレクトリー名に変更する。ちょっと手間だけど、難しいことを覚えてたり、ひねった作業をするよりスマートで簡便。急がば回れ的に便利なやり方。感動。

蛇足

ぼくは、この手の作業をする時、一つ上の階層にディレクトリーを作っていた。

$ mkdir ../dir
$ mv * ../dir
$ mv ../dir ./

この方法の欠点は二つ。一つは、一つ上に同じ名前のディレクトリーがあると mkdir の時にエラーになる。かと言って、確認するのも面倒。もう一つは、上のディレクトリーのパーミッションがない場合がある。特に管理者関係の作業をしていると、パーミッション問題にひっかかる。今回知った方法は、これら二つの欠点を全く見事にクリアーしている。いいね。

2005-10-27

Bazaar-NG のコマンドライン補完 |zsh|

Bazaar-NG には、zsh (と bash) のコマンドライン補完用ファイルが同梱されている。darcs の補完入力でも書いたけど、僕は zsh 使いなので、zsh の設定方法をば書いておく。

補完ファイルの追加

zsh 補完用のファイルは、以下の場所にある。

  • bzr-0.X.X/contrib/zsh/_bzr

これを、zsh の completion 用のディレクトリー (ここでは、~/etc/zsh とする) にコピーして、.zshrc に次のコードを追加する。

fpath=(~/etc/zsh $fpath)
autoload -U ~/etc/zsh/*(:t)
autoload -U compinit && compinit

zsh を起動し直せば、設定が反映される。

もうちょっと賢い (?) zsh 補完

[2005-10-19]、much improved zsh completion script から始まる (Bazaar-NG ML 内の) 一連のスレッドで、もう少し賢い zsh 用の completion script が公開された。このスクリプトは、[2005-10-27] 現在、Bazaar-NG の開発版には含まれていない。ファイルは以下の場所で手に入る。

設定は上と同じ。

2005-09-17

darcs で補完入力を使う |zsh|

バージョン管理システム darcs をコマンドラインで使う時の usage は次の通り。

$ darcs COMMAND OPTIONS ARGUMENTS ...

一般的な shell なら、 darcs までは補完が利く。でも、そこから先の COMMANDOPTIONS にも補完が利くと嬉しい。

僕が愛用してるのは zsh なので、zsh に darcs の補完機能を加える設定方法を書いてみた。

なお、zsh に限らず、bash や tcsh の補完についても Wiki (英語) に情報があるので参照されたし。

設定

以下のサイトの Zsh Completion の項から、 zsh completion newをダウンロード。

ダウンロードしたファイルを _darcs というファイル名に変更後、zsh の私的 completion 用ディレクトリーに入れる (ここでは ~/etc/zsh/ としよう)。

.zshrc を開いて、次のコードを追加する。

fpath=(~/etc/zsh $fpath)
autoload -U ~/etc/zsh/*(:t)
autoload -U compinit && compinit

zsh を起動し直せば、設定が反映されてるはず。

darcs の補完も、次期 zsh では標準として組み込まれるそうな。