the opy book
Fri Oct 11 22:52:24 JST 2019 (modified: Thu Oct 17 19:11:31 JST 2019)
views: 1601, keywords: この記事は最終更新日が5年以上前のものです。
4. ルールと組み合わせ
4.1 ルール
パターンとアクションを組み合わせると「パターンにマッチしたレコードに対してアクションを実行する」ということができます。例えば次の例は、入力される数字についてパターンでF1
が奇数の行だけを残し、その行の後ろに「奇数」と付加するというものです。
$ seq 3 | opy 'F1%2==1:[F1,"奇数"]'
1 奇数
3 奇数
パターンF1%2==1
の後ろにアクション[F1,"奇数"]
を並べて書くことで、パターンによるフィルタリングと、マッチした行に対する処理を書くという方法は、AWKと同じです。ただし、パターンとアクションの間には:
(コロン)を入れます。パターンとアクションを組にしたものはルールと呼ばれます。(文法上はパターン単体、アクション単体もルールとして扱われます。)
4.2 ルールの組み合わせ
ルールは複数並べることができます。これもAWKと同じですが、ルールの間にはセミコロン;
を入れます。例を示します。
$ seq 3 | opy 'F1%2==1:[F1,"奇数"];F1%2==0:[F1,"偶数"]'
1 奇数
2 偶数
3 奇数
これは、一つ前の例に、偶数の行のルールを付け加えたものです。また、2つ以上のルールを組み合わせるときは、そのうちのいくつかがパターンだけ、アクションだけでも構いません。次の例は、偶数の行の処理をパターンだけ(そのまま出力)にしたものです。
$ seq 3 | opy 'F1%2==1:[F1,"奇数"];F1%2==0'
1 奇数
2
3 奇数
さらに、一つの行に対して複数のパターンを適用することもできます。次の例はseq
の出力に対して、3の倍数のうしろにFizz
と付加する例です。
$ seq 15 | opy 'F1%3==0:{F0+=" Fizz"};[F0]'
1
2
3 Fizz
4
5
6 Fizz
・・・
最初のルールで3の倍数の行を検索し、F0
(行全体を表す文字列)の後ろにスペースとFizz
を付加しています。その後ろのルール[F0]
は全行にマッチするので、毎行実行され、F0
が出力されます。この際、Fizz
をつけたF0
はリセットされずにそのまま残っているので、3の倍数のうしろにFizz
が付きます。
4.3 BEGINパターン・ENDパターン
BEGINパターン、ENDパターンは、それぞれopyがファイルを読み込む直前、全て読み込んだ後に実行される特殊なパターンです。最も典型的な使い方は、おそらく次のようなものです。
$ seq 10 | opy 'BEGIN:{a=0};{a+=F1};END:[a]'
55
BEGINパターンで変数a
を準備し、各行でa
に値を足し、ENDパターンでa
を出力しています。
BEGIN
、END
は、それぞれB
、E
と省略できます。
$ seq 10 | opy 'B:{a=0};{a+=F1};E:[a]'
55
また、いずれも標準入力なしで利用することができるので、簡単な計算をする際に便利です。次の例は、2の3乗と3の3乗を計算して足すというものです。
$ opy 'B:{a,b=2**3,3**3};E:[a+b]'
35
また、BEGIN、ENDいずれのパターンも、複数記述することができます。記述した順に実行されるので、例えばPythonの一行一行の処理をそれぞれBEGINパターンやENDパターンにして記述することができます。これを利用して上の例を書き換えたものを示します。
$ opy 'B:{a=2**3};B:{b=3**3};E:[a+b]'
35