正規表現が弱いcsplitを使うには

以下の方法で生成されたファイルaに、csplitを使ってみます。

takk@deb8:~$ seq -f"%02g" 0 99 | sed 's/^\(.\)/\1 /' >a
takk@deb8:~$ head -20 a
0 0
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
takk@deb8:~$ 

ファイルaは、各行が空白を区切り文字として、各列昇順に並んだ数字で構成されていますが、csplitで1列目の数字毎にファイル分割するにはどうすれば良いでしょう。
もちろんsplitを使って10行毎に分割するだけでできますが、データ数が変わってもデータの内容で分割したいので、csplitを使います。
ファイルaの場合は、2列目が0になる箇所でファイル分割すればいいです。

takk@deb8:~$ csplit a '/^..0/' {*}
0
40
40
40
40
40
40
40
40
40
40
takk@deb8:~$ 

正しく分割できているか確認してみます。

takk@deb8:~$ paste -d"|" xx*
|0 0|1 0|2 0|3 0|4 0|5 0|6 0|7 0|8 0|9 0
|0 1|1 1|2 1|3 1|4 1|5 1|6 1|7 1|8 1|9 1
|0 2|1 2|2 2|3 2|4 2|5 2|6 2|7 2|8 2|9 2
|0 3|1 3|2 3|3 3|4 3|5 3|6 3|7 3|8 3|9 3
|0 4|1 4|2 4|3 4|4 4|5 4|6 4|7 4|8 4|9 4
|0 5|1 5|2 5|3 5|4 5|5 5|6 5|7 5|8 5|9 5
|0 6|1 6|2 6|3 6|4 6|5 6|6 6|7 6|8 6|9 6
|0 7|1 7|2 7|3 7|4 7|5 7|6 7|7 7|8 7|9 7
|0 8|1 8|2 8|3 8|4 8|5 8|6 8|7 8|8 8|9 8
|0 9|1 9|2 9|3 9|4 9|5 9|6 9|7 9|8 9|9 9
takk@deb8:~$ 

データ数がきれいに10個ずつ並んでいたので簡単でした。
不揃いの場合はどうでしょうか。2列目の0が存在しない場合は、分割場所を指定するのに困ります。

csplitを使う前に、テキスト整形をして印をつければ良いだけです。

ではさきほどのファイルaから以下のようにファイルbを作ってこれを分割したいと思います。

takk@deb8:~$ sort -R a | head -50 | sort >b
takk@deb8:~$ pr -t5J b
0 1	1 7	3 7	5 4	7 8
0 2	1 9	4 0	5 8	7 9
0 3	2 0	4 4	5 9	8 0
0 4	2 6	4 5	6 4	8 2
0 7	2 7	4 7	6 7	8 6
0 8	2 9	4 8	7 0	9 0
0 9	3 0	4 9	7 1	9 1
1 0	3 3	5 1	7 4	9 4
1 5	3 4	5 2	7 6	9 7
1 6	3 6	5 3	7 7	9 9
takk@deb8:~$ 

csplitの正規表現はsedやperlほど高機能ではないため、あらかじめcsplitが使えるテキスト構成にしておけば良いです。

takk@deb8:~$ seq 100 | perl -ne 'printf"%d %d\n",int rand 10,int rand 10' | sort | uniq >a 
takk@deb8:~$ head a
0 0
0 2
0 4
0 6
0 7
1 1
1 3
1 4
1 5
1 7
takk@deb8:~$ 

1列目の数字が変化したら行頭のマークも変化するテキストにperlで置換します。

takk@deb8:~$ perl -pe '/^(\d)/;$a=":";$a="|" if($pre==$1);$_=$a.$_;$pre=$1' <b > c
takk@deb8:~$ 

後は、csplitで行頭のマークで分割します。

takk@deb8:~$ csplit c '/^:/' {*}
35
25
20
25
30
30
10
35
15
25
takk@deb8:~$ ls x*
xx00  xx01  xx02  xx03  xx04  xx05  xx06  xx07  xx08  xx09
takk@deb8:~$ 

結果です。各ファイル1列目の数字で分割されてますね。

takk@deb8:~$ paste xx* | expand -t5
|0 1 :1 0 :2 0 :3 0 :4 0 :5 1 :6 4 :7 0 :8 0 :9 0
|0 2 |1 5 |2 6 |3 3 |4 4 |5 2 |6 7 |7 1 |8 2 |9 1
|0 3 |1 6 |2 7 |3 4 |4 5 |5 3      |7 4 |8 6 |9 4
|0 4 |1 7 |2 9 |3 6 |4 7 |5 4      |7 6      |9 7
|0 7 |1 9      |3 7 |4 8 |5 8      |7 7      |9 9
|0 8                |4 9 |5 9      |7 8      
|0 9                               |7 9      
takk@deb8:~$ 

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA