Mac(BSD 系) とGNU Linux の間では実装が異なるコマンドがあります。例えばmv。
GNU Linux のmv
- -t オプションでターゲットディレクトリを指定できる
これは、xargs とコンボする際に必要。例えば、数字をファイル名に含むファイルをroutine に移動した場合。
$ ls -p | egrep "[[:digit:]]" | grep -v "/" | xargs mv -t routine
Mac のmv
- Mac のmv には-t オプションがない
なので、こうなる。
$ ls -p | egrep "[[:digit:]]" | grep -v "/" | xargs mv -t routine mv: illegal option -- t
ls, find とmv はコンボしたいだろJK ( ゚д゚)
$ ls -p | egrep "[[:digit:]]" | grep -v "/" | xargs -I{} mv {} routine
とか面倒だろ( ゚д゚)
そこでGNU coreutils ですよ
実は、GNU coreutilsのcpやmvにはxargsと組み合わせて使うためのオプションが用意されています。coreutilsのinfoにも書いてありますが、「-t」または「--target-directory」オプションでdestinationのディレクトリを指定できます。
$ find . -name \*~ -print0 | xargs -0 mv -t /var/tmp
僕はMac使いですけど、MacPortsでGNU coreutilsをインストールしています。こんなメリットがあるんだから標準のmvを捨ててGNUに浮気するのも当然ですよね?
そうなんです。GNU coreutils を入れれば、GNU Linux 版のコマンドが使えるのです。UNIX上の基本的なコマンドを集めたGNUのパッケージがGNU coreutils です。
macports からインストールすることができます。
$ sudo port install coreutils
実はlsはglsという名前でインストールされている。cp、mv、df、cat、odもそれぞれgcp、gmv、gdf、gcat、godという名前で入る(godって……)。おわかりのとおり、コマンド全部が「g」から始まるようになっている。
ここにあるように、coreutils で入れたコマンドを使うには、先頭に「g」をつける必要があります。これで、xargs とmv がコンボできるようになりました。
$ ls -p | egrep "[[:digit:]]" | grep -v "/" | xargs gmv -t routine
g が先頭につくのが嫌
そういう方はalias を設定するのが良いようです。「+with_default_names」というバライアントをつけてインストールするとg なしにコマンドを使えるようになりますが、次のような問題点があります。
つい先日MacPortsのメーリングリストでも「lsはlsとして、gをつけない普通の名前で/opt/local/binに入れるようにしませんか」という提案がなされたのだが(ソース)、「既存のシェルスクリプトはOS標準の(BSD系の)lsを想定して書かれているから動かなくなったら困る」という理由で却下されている。
これを回避するにはalias を使うのがよさそうです。