1 概要

https://rubygems.org/gems/tefil に公開してあります。

テキストフィルターコマンドのフレームワークと それを使った幾つかのフィルターコマンドを提供します。

2 コマンド

2.1 共通事項

2.1.1 オプション

2.2 calc

bc で 小数点の前のゼロが省略されたりするのが不便なので作りました。 また、Ruby っぽい関数指定ができるようにしました。

% echo '1+2' | calc
#=> 3

% echo '1.0+2.0' | calc
#=> 3.0

% echo 'sqrt(2)' | calc
#=> 1.41421356237309504880

% echo 'l(2)' | calc
#=> 0.69314718055994530941

% echo 'e(1)' | calc
#=> 2.71828182845904523536

2.3 columnanalyze

ps や qstat の出力は数千行以上にもなり得ます。 これらの表形式のストリームを簡単に取り纏めて把握するためのコマンドです。

example ディレクトリに実行例が同梱されています。 qstat.out は gridengine の qstat コマンドの出力で、以下のような長いファイルです。

job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID 
-----------------------------------------------------------------------------------------------------------------
 205712 0.75000 vasp-all.q alice        r     05/11/2017 15:37:12 Tc.q@Tc18.calc.atom                4        
 205714 0.75000 vasp-all.q alice        r     05/11/2017 15:37:12 Tc.q@Tc19.calc.atom                4        
 269156 0.40572 vasp-Tc.qs bob          r     05/30/2017 02:43:57 Tc.q@Tc05.calc.atom                4        
 269159 0.40572 vasp-Tc.qs bob          r     05/30/2017 03:47:12 Tc.q@Tc02.calc.atom   
 (snip)

2.3.1 引数なしで実行

example/columnanalyze/ ディレクトリで以下のように実行すると、 以下のような出力が得られます。

% cat qstat.out | columnanalyze
1      2       3          4       5     6                   7                   8     9
job-ID prior   name       user    state submit/start at     queue               slots ja-task-ID
205712 0.75000 vasp-all.q alice   r     05/11/2017 15:37:12 Tc.q@Tc18.calc.atom 4
205714 0.75000 vasp-all.q alice   r     05/11/2017 15:37:12 Tc.q@Tc19.calc.atom 4
269156 0.40572 vasp-Tc.qs bob     r     05/30/2017 02:43:57 Tc.q@Tc05.calc.atom 4
269159 0.40572 vasp-Tc.qs bob     r     05/30/2017 03:47:12 Tc.q@Tc02.calc.atom 4
(snip)
293952 0.25011 vaspgeomop dave    qw    05/30/2017 11:51:05                     4

All:       78
Extracted: 78 ()

key head            types
1   job-ID          78
2   prior           29
3   name            7
4   user            5
5   state           4
6   submit/start at 49
7   queue           25
8   slots           2
9   ja-task-ID      2

「All: 78」というのはストリームで流れてきた行数です。 「Extracted: 78 ()」というのはそのうち抽出した行数です。 ここでは抽出条件を指定していないので All と同じ数になっています。

key はコマンドで扱う列番号です。 sort コマンドと同様に 1始まりにしてあります。

head はストリームで流れてきた1行目における要素の内容です。 多くのコマンドでタイトルとなっている事でしょう。 types はそれぞれの列におけるユニークな要素の数です。 たとえば job-ID は全てのジョブで一意であるため、 All と同じ数になっています。 user は 5種類の名前がこの位置に現れたことを示しています。

なお、 qstat.out で現れた横棒は無視されています。

-----------------------------------------------------------------------------------------------------------------

プログラムとしては、単一文字種のみで構成された行を無視するようにしています。

2.3.2 要素解析

各ユーザの出現数を調べてみましょう。 以下のように、解析したい対象のキー番号をコマンドライン引数に含めます。

% cat qstat.out| columnanalyze 4
(snip)

key analysis
(key=4)
user    1
dave    8
charlie 10
bob     22
alice   37

ストリームのうちで出現する回数の昇順で表示されます。 user は1行目のタイトルですね。

複数のキーを一度に指定できます。

% cat qstat.out| columnanalyze 4 5
(snip)

key analysis
(key=4)
user    1
dave    8
charlie 10
bob     22
alice   37

(key=5)
state 1
Eqw   2
r     23
qw    52

2.3.3 絞り込み

bob の出現する情報だけを取得し、他を捨てたいとしましょう。 以下のように、対象のキー番号と文字列をイコールで結んでコマンドライン引数に含めます。

% cat qstat.out| columnanalyze 4=bob
1      2       3          4    5     6                   7                   8     9
job-ID prior   name       user state submit/start at     queue               slots ja-task-ID
269156 0.40572 vasp-Tc.qs bob  r     05/30/2017 02:43:57 Tc.q@Tc05.calc.atom 4
269159 0.40572 vasp-Tc.qs bob  r     05/30/2017 03:47:12 Tc.q@Tc02.calc.atom 4
269161 0.40572 vasp-Tc.qs bob  r     05/30/2017 10:01:27 Tc.q@Tc06.calc.atom 4
269162 0.40572 vasp-Tc.qs bob  r     05/30/2017 10:52:12 Tc.q@Tc07.calc.atom 4
293923 0.25243 vasp-Pd.qs bob  r     05/30/2017 09:45:27 Pd.q@Pd12.calc.atom 4
293935 0.25081 vasp-Pd.qs bob  r     05/30/2017 11:18:42 Pd.q@Pd06.calc.atom 4
293936 0.25076 vasp-Pd.qs bob  r     05/30/2017 11:25:57 Pd.q@Pd09.calc.atom 4
293937 0.25068 vasp-Pd.qs bob  r     05/30/2017 11:26:57 Pd.q@Pd07.calc.atom 4
293938 0.25067 vasp-Pd.qs bob  r     05/30/2017 11:32:12 Pd.q@Pd05.calc.atom 4
293939 0.25066 vasp-Pd.qs bob  r     05/30/2017 11:33:27 Pd.q@Pd11.calc.atom 4
293940 0.25064 vasp-Pd.qs bob  r     05/30/2017 11:36:42 Pd.q@Pd13.calc.atom 4
293941 0.25064 vasp-Pd.qs bob  r     05/30/2017 11:37:57 Pd.q@Pd15.calc.atom 4
269299 0.38432 vasp-Tc.qs bob  qw    05/25/2017 10:26:16                     4
269300 0.38430 vasp-Tc.qs bob  qw    05/25/2017 10:27:25                     4
269301 0.38428 vasp-Tc.qs bob  qw    05/25/2017 10:28:36                     4
269302 0.38426 vasp-Tc.qs bob  qw    05/25/2017 10:29:17                     4
269314 0.38410 vasp-Tc.qs bob  qw    05/25/2017 10:38:05                     4
269320 0.38354 vasp-Tc.qs bob  qw    05/25/2017 11:08:47                     4
269321 0.38352 vasp-Tc.qs bob  qw    05/25/2017 11:09:36                     4
293942 0.25063 vasp-Pd.qs bob  qw    05/30/2017 11:22:57                     4
293943 0.25060 vasp-Pd.qs bob  qw    05/30/2017 11:24:33                     4
293944 0.25059 vasp-Pd.qs bob  qw    05/30/2017 11:24:55                     4

All:       78
Extracted: 22 (3=bob)

key head            types
1   job-ID          22
2   prior           18
3   name            2
4   user            1
5   state           2
6   submit/start at 22
7   queue           13
8   slots           1
9   ja-task-ID      1

複数条件による絞り込みもできます。

% cat qstat.out| columnanalyze 4=bob 5=r
1      2       3          4    5     6                   7                   8     9
job-ID prior   name       user state submit/start at     queue               slots ja-task-ID
269156 0.40572 vasp-Tc.qs bob  r     05/30/2017 02:43:57 Tc.q@Tc05.calc.atom 4
269159 0.40572 vasp-Tc.qs bob  r     05/30/2017 03:47:12 Tc.q@Tc02.calc.atom 4
269161 0.40572 vasp-Tc.qs bob  r     05/30/2017 10:01:27 Tc.q@Tc06.calc.atom 4
269162 0.40572 vasp-Tc.qs bob  r     05/30/2017 10:52:12 Tc.q@Tc07.calc.atom 4
293923 0.25243 vasp-Pd.qs bob  r     05/30/2017 09:45:27 Pd.q@Pd12.calc.atom 4
293935 0.25081 vasp-Pd.qs bob  r     05/30/2017 11:18:42 Pd.q@Pd06.calc.atom 4
293936 0.25076 vasp-Pd.qs bob  r     05/30/2017 11:25:57 Pd.q@Pd09.calc.atom 4
293937 0.25068 vasp-Pd.qs bob  r     05/30/2017 11:26:57 Pd.q@Pd07.calc.atom 4
293938 0.25067 vasp-Pd.qs bob  r     05/30/2017 11:32:12 Pd.q@Pd05.calc.atom 4
293939 0.25066 vasp-Pd.qs bob  r     05/30/2017 11:33:27 Pd.q@Pd11.calc.atom 4
293940 0.25064 vasp-Pd.qs bob  r     05/30/2017 11:36:42 Pd.q@Pd13.calc.atom 4
293941 0.25064 vasp-Pd.qs bob  r     05/30/2017 11:37:57 Pd.q@Pd15.calc.atom 4

All:       78
Extracted: 12 (3=bob 4=r)

key head            types
1   job-ID          12
2   prior           8
3   name            2
4   user            1
5   state           1
6   submit/start at 12
7   queue           12
8   slots           1
9   ja-task-ID      1

絞り込んだ上で、情報を解析することができます。 以下はさらにキー番号3の要素で解析しています。

% cat qstat.out| columnanalyze 4=bob 5=r 3

2.3.4 備考

2.3.4.1 要素の区切り

このコマンドは等幅フォントによる表形式のテキスト出力を想定しています。 全ての行でスペースになっている桁は区切りの領域に属し、 どれかの行でスペース以外の文字が入っている桁は文字列の領域と見做します。 以下に例を示します。

abcde ghij lmn pq       y 
 bc e ghi    nopqr t    yz
a cd      k        t   xyz
--------------------------
ooooo oooooooooooo o   ooo
--1-- -----2------ 3   -4-

上3行が解析対象の行です。 この場合、[f,k,s,u,v,w] 桁 の桁が全ての行で空白になっているので区切りになります。 ただし、[u,v,w] の桁は一続きの区切りなので間に空文字列を要素として見做したりしません。 5行目が3行の投影となっていて、 6行目にキー番号を示しています。

2.3.4.2 コンパクトな出力

ストリーム各行の出力はそのまま出すのではなく、 動的に無駄な空白桁を減らしてコンパクトに出力するようにしています。

job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID 
-----------------------------------------------------------------------------------------------------------------
 205712 0.75000 vasp-all.q alice        r     05/11/2017 15:37:12 Tc.q@Tc18.calc.atom                4        

↑ qstat.out。 ↓ columnanalyze の出力。

1      2       3          4       5     6                   7                   8     9
job-ID prior   name       user    state submit/start at     queue               slots ja-task-ID
205712 0.75000 vasp-all.q alice   r     05/11/2017 15:37:12 Tc.q@Tc18.calc.atom 4

2.3.4.3 引数

このコマンドはファイル名を引数に取ることができません。 理由は、ファイルから取得するよりも、 絞り込み条件と解析対象を修正しつつ何度も実行して情報を掘り出すことがメインの目的で、 ファイルからのストリームを扱うことはあまりなさそうだと判断したためです。 ファイルからストリームをとるときは cat から パイプするなどしてください。