cut コマンド 2016/06/11
タブ区切りでフィールドを選択して出力する、または各行の中の一部を範囲指定して出力するコマンド。
cutコマンドの使用例と、同じことをするPerlワンライナーの例
## タブ区切りで最初の列と3列目だけを抽出して、タブ区切りで出力する
$ cut -f1,3 foo.txt
$ cat foo.txt | cut -f1,3
$ cat foo.txt | perl -anle 'print "$F[0]\t$F[2]"'
## 以下のようにしても列の順番は入れ替えてくれない
$ cut -f3,1 foo.txt
## Perlならできる
$ cat foo.txt | perl -anle 'print "$F[2]\t$F[0]"'
## 各行の4文字目以降を出力する
$ cut -b4- foo.txt
$ cat foo.txt | cut -b4-
$ cat foo.txt | perl -MEncode -nle 'print encode_utf8(substr(decode_utf8($_), 3))'
cutコマンドでできる処理であれば、Perlワンライナーを書くよりも簡単にできる。
インストール 2016/03/17
Coreutilsというパッケージに入っているので、CentOSにもUbuntuにも始めから入っている。
オプション 2016/06/11
-b
- フィールド単位ではなくバイト単位で抽出する範囲を指定する
-c
- フィールド単位ではなく文字単位で抽出する範囲を指定する。
いまの実装では
-b
と同じ。 --complement
- 抽出するフィールドは、
-f
で指定する番号以外のフィールドとする。 -d
- フィールドのデリミタを指定する
-f
- 抽出するフィールドの番号を指定する。1から始まる番号でハイフンでの範囲指定や
コンマ区切りで複数指定できる。
残念なことに
-f3,1
とやっても-f1,3
と同じになり、フィールドの並び替えは できない。 --help
- ヘルプ表示
--version
- バージョン表示
--
というパラメータを渡すとそれ以降のパラメータをオプションではなくファイル名とみなしてくれるので、
-
で始まるファイル名を扱いたい場合に使うとよい。
-c
オプションは -b
と同じ
2016/06/11
-c
は文字単位で単位指定するオプションで、-b
とはマルチバイトの文字があったときに挙動が変わるはずだが、
cutのソースコードを見るといまは -b
と -c
の実装はまったく同じのようである。
https://github.com/coreutils/coreutils/blob/a3311c966e34f2d9f8aa6b1de31b211124803d02/src/cut.c#L507
マニュアルを見ても確かに、いまは同じだが国際化対応をしたら挙動が変わる、というようなことが書いてある。
HOWTO
フィールドの区切りをタブではなくスペースにして処理するには 2013/06/17
cat <file-path> | cut -d' ' -f1,3
1つ以上の連続するスペースまたはタブ文字を区切りとして処理するには 2015/11/08
cut
コマンドはデフォルトではカラムの区切りはタブ文字であり、
cut -d' ' -f1,3
のようにすれば区切り文字はスペースになるが、いずれにしても区切り文字が連続する箇所はそこに空の列があるものとみなす。
そのため以下のような位置揃えをしてあるファイルを処理するのは苦手である。
$ cat foo.txt
0 29 Danny m
1 24 Jess m
2 29 Joey m
3 10 D.J. f
4 5 Steph f
5 0 Michelle f
こういう場合は以下のように連続するスペースを1つのタブに置換してしまうと楽である。
$ cat foo.txt | sed 's/[\t ]\+/\t/g' | cut -f3
Danny
Jess
Joey
D.J.
Steph
Michelle
スペースの置換はsed
でなくてもperl
のワンライナーでもできるが、どうせperl
を使うなら、
cut
ですることもperl
でやればいい。
$ cat foo.txt | perl -F'\s+' -anle 'print $F[2]'
Danny
Jess
Joey
D.J.
Steph
Michelle
またはawk
コマンドを使ってもよい。
awk
ではデフォルトで連続するスペースを1つの区切りとみなされる。
$ cat $p/tmp/test.txt | awk '{print $3}'
Danny
Jess
Joey
D.J.
Steph
Michelle
タブをコマンドラインから指定するには 2016/06/11
cut
は -f
でフィールドを指定した場合、デフォルトでタブ区切りだが、コマンドラインからどうしてもタブ区切りであることを指定したい場合は、以下のように書けなくもない。
# 最初のカラムだけを表示
cut -d$'\t' -f1
sort
でも似たような書き方でできる。
zshでは $
がいらないみたい。
シェルスクリプトの変数に入っている文字列の一部を切り出すには 2016/05/11
ファイルではなく変数の値から一部を抜き出すには ${VAR:S:L}
という書き方をする。すると、S
からL
文字分の部分文字列を抜き出せる。
s="abcdef"
echo ${s:2:2}
# => cd