physpolyglot

主にPC関連の自分用メモのうち、役立ちそうなものを共有します。

zargsとお手軽並列計算

zargsはxargsのzsh版とでもいうべきもの。
zshの拡張グロブでファイルリストを生成し、それぞれのファイルについて処理を行うことができる。

シェルのグロブパターン*1で長過ぎるファイルリストをコマンドに渡すと、 シェルに怒られてしまい*2処理を実行できないときがある。

そんなときに活躍するのがxargsとかzargsとか。

xargsも便利だとおもうのだけど、findで欲しいファイルを検索してくるのは面倒くさい……。というかfindの使い方覚えてない。
zshの拡張グロブなら直感的にファイルを指定できるので最高です!
従来のシェルと同様のファイル名生成はもちろん、ファイル属性も指定できるし、編集子を使えば拡張子を取り除くなどの簡単な編集さえ出来てしまう……。神!

拡張グロブについてはそのうち自分用メモとしてまとめるつもりです。 *3

zargsを使う場合は、事前にautoloadをしておく。もちろんzsh限定。

autoload zargs

zargsの基本的な使い方はこんな感じ。

zargs OPTIONS -- GLOB -- COMMAND

例えば、

zargs -- some_dir/*.dat -- ./some_program

とするとsome_programの引き数にsome_dir/*.datにマッチする全てのファイルが渡され、 順次実行される。

-Pオプションで並列プロセス数を設定することが出来る。
-P2で2プロセス同時実行とか。
-P0にすると最大のプロセス数が設定される。

zargs -P0 -- some_dir/*.dat -- ./some_program

これで簡単並列処理ができる。本当に簡単。

zargsはシェル配列に入ったものに対しても処理を行うことが出来る。

array=(hoge hige hage)
zargs -P0 -- ${=array} -- ./some_program

=を使ってシェル配列を展開してやればよい。
この例の場合、hoge,hige,hageそれぞれがsome_programに渡される。

コマンドが複数の引数を受け付ける場合にグロブ展開したものを入力する場所を指定したいなら、-iオプションでプレースホルダを指定できる。

-istringとすると(stringは任意の文字列でプレースホルダとなる)、二つ目の--の後でstringの部分にグロブの展開結果が代入される。

zargs -P0 -ifile -- ./*.dat -- ./some_program ${hoge} file ${fuga}

zargsと拡張グロブと何らかの言語のワンライナーを使いこなせれば、 複雑な処理でも1行で簡単に書けてうれしいですね。

*1:アスタリスクとか

*2:Argument list too long

*3:なぜこんな便利な機能なのにネット上にまとめが見つからないのだろうか……