Mac のコマンドを強化するGNU coreutils

Mac(BSD 系) とGNU Linux の間では実装が異なるコマンドがあります。例えばmv。

GNU Linux のmv

これは、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使いですけど、MacPortsGNU 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 を使うのがよさそうです。