MacやLinux、UNIXライクなOSなら大体入ってるcutコマンド。自分の周りだとawkに慣れてくるとあまり使わなくなることが多い印象なのだけど、地味にawkだと記述が辛い処理でも簡単に処理できることもある。 今回は、そんなcutコマンドについて覚えておくと便利な使い方についてまとめてみることとする。

なお、対象はGNU版とする。MacやBSD等ではバンドルされてないので注意。

1. 基本的な使い方

cutコマンドでは、以下のように実行することでタブ区切りのデータから指定列を抽出することができる。 例をみてわかるように、範囲指定や指定列まで、指定列以降といった指定が簡単に行えるようになっている。

cut -f 抜き出すフィールドの番号

blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5 | tr ' ' '\t'
a01     a02     a03     a04     a05
b01     b02     b03     b04     b05
c01     c02     c03     c04     c05
d01     d02     d03     d04     d05
e01     e02     e03     e04     e05
blacknon@BS-PUB-UBUNTU-01:~$ # cutで3列目を抜き出す場合
blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5 | tr ' ' '\t' | cut -f3
a03
b03
c03
d03
e03
blacknon@BS-PUB-UBUNTU-01:~$ # cutで2,4列目を抜き出す場合
blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5 | tr ' ' '\t' | cut -f2,4
a02     a04
b02     b04
c02     c04
d02     d04
e02     e04
blacknon@BS-PUB-UBUNTU-01:~$ # cutで2列目~4列目を抜き出す場合
blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5 | tr ' ' '\t' | cut -f2-4
a02     a03     a04
b02     b03     b04
c02     c03     c04
d02     d03     d04
e02     e03     e04
blacknon@BS-PUB-UBUNTU-01:~$ # cutで3列目までを抜き出す場合
blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5 | tr ' ' '\t' | cut -f-3
a01     a02     a03
b01     b02     b03
c01     c02     c03
d01     d02     d03
e01     e02     e03
blacknon@BS-PUB-UBUNTU-01:~$ # cutで3列目以降を抜き出す場合
blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5 | tr ' ' '\t' | cut -f3-
a03     a04     a05
b03     b04     b05
c03     c04     c05
d03     d04     d05
e03     e04     e05

デフォルトではデリミタはタブになっているが、-dオプションを用いることで変更ができる。

cut -d <デリミタ> -f ...
blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5
a01 a02 a03 a04 a05
b01 b02 b03 b04 b05
c01 c02 c03 c04 c05
d01 d02 d03 d04 d05
e01 e02 e03 e04 e05
blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5 | cut -d ' ' -f 3
a03
b03
c03
d03
e03

2. 区切り文字を含まない行を対象外にする

区切り文字を含まない行を対象外にする場合は、-sオプションを付与する。

blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5
a01 a02 a03 a04 a05
b01 b02 b03 b04 b05
c01 c02 c03 c04 c05
d01 d02 d03 d04 d05
e01 e02 e03 e04 e05
blacknon@BS-PUB-UBUNTU-01:~$ # 3行目だけデリミタをスペースからカンマに
blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5 | sed '3s/ /,/g'
a01 a02 a03 a04 a05
b01 b02 b03 b04 b05
c01,c02,c03,c04,c05
d01 d02 d03 d04 d05
e01 e02 e03 e04 e05
blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5 | sed '3s/ /,/g' | cut -d' ' -f 3
a03
b03
c01,c02,c03,c04,c05
d03
e03
blacknon@BS-PUB-UBUNTU-01:~$ echo {a..e}{01..05} | xargs -n5 | sed '3s/ /,/g' | cut -s -d' ' -f 3
a03
b03
d03
e03

3. 抜き出す範囲をバイト数・文字数で指定する

cutでは、抜き出す範囲をフィールドではなく、バイトや文字数で指定することもできる。 バイトで抜き出す場合は「-b」、文字数で抜き出す場合は「-c」で行える。

blacknon@test-ubuntu:~$ echo {a..e}{01..05} | xargs -n5 | tr -d ' '
a01a02a03a04a05
b01b02b03b04b05
c01c02c03c04c05
d01d02d03d04d05
e01e02e03e04e05
blacknon@test-ubuntu:~$ echo {a..e}{01..05} | xargs -n5 | tr -d ' ' | cut -b 3-5
1a0
1b0
1c0
1d0
1e0
blacknon@test-ubuntu:~$ echo {a..e}{01..05} | xargs -n5 | tr -d ' ' | cut -c 1-3,7-9
a01a03
b01b03
c01c03
d01d03
e01e03

4.指定した範囲以外を出力する

GNU版のcutコマンドでは、「--complement」オプションを付与することで、指定した範囲以外の箇所を出力させる事ができる(これは特にawkだとちょっと難しいので、cutでやったほうがいいと思う)。

blacknon@test-ubuntu:~$ echo {a..e}{01..05} | xargs -n5
a01 a02 a03 a04 a05
b01 b02 b03 b04 b05
c01 c02 c03 c04 c05
d01 d02 d03 d04 d05
e01 e02 e03 e04 e05
blacknon@test-ubuntu:~$ echo {a..e}{01..05} | xargs -n5 | cut -d' ' -f 2-3
a02 a03
b02 b03
c02 c03
d02 d03
e02 e03
blacknon@test-ubuntu:~$ echo {a..e}{01..05} | xargs -n5 | cut -d' ' -f 2-3 --complement
a01 a04 a05
b01 b04 b05
c01 c04 c05
d01 d04 d05
e01 e04 e05

5. 出力内容のデリミタを指定する

GNU cutでは「--output-delimiter」オプションを使うことで、出力のデリミタを指定することができる。

blacknon@test-ubuntu:~$ echo {a..e}{01..05} | xargs -n5 | cut -d' ' -f 2-4
a02 a03 a04
b02 b03 b04
c02 c03 c04
d02 d03 d04
e02 e03 e04
blacknon@test-ubuntu:~$ echo {a..e}{01..05} | xargs -n5 | cut -d' ' -f 2-4 --output-delimiter="-"
a02-a03-a04
b02-b03-b04
c02-c03-c04
d02-d03-d04
e02-e03-e04