【Linux入門】cutコマンドの基本を学ぶ

ファイル処理の際にデータを細かく切り出したり、必要な部分だけ抽出したりしたいときに便利なのがcutコマンドです。

本稿ではcutコマンドの使い方を丁寧に解説します。


 cutコマンドの用法

cutコマンドの基本的な使い方は以下のようになります。

 

$ cut オプション 対象文字列

 

(※「$ 」はコマンド受付中のマークです。既に表示されているので皆さんが入力する必要はありません(環境によっては「# 」になっているかもしれません))

cutコマンドは単独で使うというよりは、echoやcat、sedなどの出力結果を受けて、細かい部分をさらに切り出す、というときに用いられることが多いコマンドです。また、cutコマンドも多分に漏れず引数が必ず必要ですが、1つ以上のオプションをちゃんと指定しないとエラーを返すという少し珍しいコマンドと言えるかもしれません。

今回は「nobel.txt」というデータセットを用いて使用法を見ていきましょう!

実際にコマンドを試してみたい方のために日本人ノーベル賞受賞者のうち、最初の10人の受賞年、名前(生年)、受賞分野のリストを作りましたので、必要に応じてご活用下さい。

» 日本人ノーベル賞受賞者最初の10人のリスト

1949/Hideki Yukawa(1907-1981)/Physics
1965/Sin-Itiro Tomonaga(1906-1979)/Physics
1968/Yasunari Kawabata(1899-1972)/Literature
1973/Reona Esaki(Leo Esaki)(1925-)/Physics
1974/Eisaku Sato(1901-1975)/Peace
1981/Kenichi Fukui(1918-1998)/Chemistry
1987/Susumu Tonegawa(1939-)/Physiology or Medicine
1994/Kenzaburo Oe(1935-)/Literature
2000/Hideki Shirakawa(1936-)/Chemistry

» 閉じる

cutコマンドを使う際はどこをどのように切り出すのかを指示してあげる必要があります。以下、各オプションを見ていきましょう。

 

 バイト数で斬る(-b)

cutコマンドでは切り出すバイト数を指定することができます。例えばnobel.txtの各行の4バイト目を表示するには以下のようにします。

 

$ cut -b 4 nobel.txt

9
5
8
3
4
1
7
4
0

 

1文字だけが欲しい場合はともかく、これだけでは何が何だか分かりません。

そこで「1バイト目から4バイト目」を切り出してみましょう。こういうときはハイフンを使用します。

 

$ cut -b 1-4 nobel.txt

1949
1965
1968
1973
1974
1981
1987
1994
2000

 

これで受賞年を切り出すことができました。いまは「1」と最初のバイト数を指定しましたが、先頭のバイト数や文字を起点とする場合は

 

$ cut -b -4 nobel.txt

 

のように「1」の部分を省略することができます。また、日本語対応の環境であれば「-n」オプション(2バイト以上の文字を途中で切らないようにするオプション)と併用することもあります。

 

 文字数で斬る(-c)

英数字の場合は-bオプションも-cオプションもほとんど変わらないので、こちらの-cオプションの方を使う機会が多いのではないかと思います。

 

$ cut -c 5- nobel.txt

/Hideki Yukawa(1907-1981)/Physics
/Sin-Itiro Tomonaga(1906-1979)/Physics
/Yasunari Kawabata(1899-1972)/Literature
/Reona Esaki(Leo Esaki)(1925-)/Physics
/Eisaku Sato(1901-1975)/Peace
/Kenichi Fukui(1918-1998)/Chemistry
/Susumu Tonegawa(1939-)/Physiology or Medicine
/Kenzaburo Oe(1935-)/Literature
/Hideki Shirakawa(1936-)/Chemistry

 

ここでは5文字目以降を表示してみました。使い方は-bオプションと変わりません。また、カンマで区切れば複数の部分を切り出すこともできます。以下の例では6文字目~10文字目、18文字目~24文字目を切り出しています。

 

$ cut -c 6-10,18-24 nobel.txt

Hideka(1907-
Sin-Imonaga(
Yasunabata(1
ReonaLeo Esa
Eisak1901-19
Kenici(1918-
Susumawa(193
Kenza(1935-)
Hidekkawa(19

 

空白文字も含めてちゃんと抜き出せていますが、これでは意味のある文字列になっていませんね。

「-c」オプションは決まった形式のファイルや出力結果を整理するときに用いますが、文字数が様々に変動する出力に対応するのは難しいと言えます。このような場合はフレキシブルに対応できる「-d」オプションと「-f」オプションの合わせ技を使います。

 

 区切り文字で斬る(-d,-f)

cutコマンドで最も強力な武器(?)がデリミタ(区切り文字)を指定したフィールド単位の切り出し機能です。このコマンドの書式は以下の通りです。

 

$ cut -d "区切り文字" -f n 対象文字列

 

「-d」オプションで区切り文字を指定して幾つかのフィールドに分け、「-f」オプションで左からn番目のフィールドを取ってくる、というコマンドです。

例えば

1949/Hideki Yukawa(1907-1981)/Physics

という一連の文字列は「/」という文字によって3つの領域に分けられています。この場合、nobel.txtの各行の真ん中、つまり2番目のフィールドを取ってきたい場合は次のようにします。

 

$ cut -d "/" -f 2 nobel.txt

Hideki Yukawa(1907-1981)
Sin-Itiro Tomonaga(1906-1979)
Yasunari Kawabata(1899-1972)
Reona Esaki(Leo Esaki)(1925-)
Eisaku Sato(1901-1975)
Kenichi Fukui(1918-1998)
Susumu Tonegawa(1939-)
Kenzaburo Oe(1935-)
Hideki Shirakawa(1936-)

 

同様に、受賞分野を切り出したいときは

 

$ cut -d "/" -f 3 nobel.txt

 

とします。受賞年と受賞分野を一緒に抜き出すときはカンマで指定すればOKです。

 

$ cut -d "/" -f 1,3 nobel.txt

1949/Physics
1965/Physics
1968/Literature
1973/Physics
1974/Peace
1981/Chemistry
1987/Physiology or Medicine
1994/Literature
2000/Chemistry

 

なお、デリミタ(区切り文字)は1文字しか設定できません。2文字以上を指定するとエラーが返ってきます。

$ cut -d "19" -f 1 nobel.txt

cut: the delimiter must be a single character
Try `cut --help' for more information.

 

勿論、ここまで紹介してきた切り出し操作は正規表現を用いたsedコマンドによっても可能ですが、ユーザーにとってはcutコマンドの方が分かりやすいと言えます。cutコマンドでは「-d」オプションを使用した複数フィールドの切り出しが特に有用です。

デリミタに空白(スペース)を使用することもできますが、タブ文字などがあると空白文字の数が変動しますのでcutコマンドはやや不向きです。こういうときは配列に入れてしまうか、awkコマンドで要素ごとに抜き出した方が良い気がします。

cutコマンドだけ、であったり、sedコマンドだけ、というように一つのコマンドに固執するのではなく、色々なコマンドを柔軟に使えると作業効率も上がると思います。(シェル芸人を目指している方におかれてはその限りではありませんが・・・)

 

 Tips1:ディレクトリのパスを取ってくる

nobel.txtというファイルのパスが

「\home\user\ppp\qqq\rrr\nobel.txt」

であるとき、「\home\user\ppp\qqq\rrr」の部分は、文字列をひっくり返すrevコマンドを用いて切り出すことができます。

 

$ echo "/home/user/ppp/qqq/rrr/nobel.txt" | rev | cut -d "/" -f 2- | rev

/home/user/ppp/qqq/rrr

(実際にはdirnameコマンドで一発ですが・・・)

 

 Tips2:アウトプットの区切り文字を変える

「–output-delimiter=”xxx”」というオプションで指定することで出力時のデリミタをxxxに変えることができます。

 

$ cut -d "/" -f 1-2 nobel.txt --output-delimiter="%"

1949%Hideki Yukawa(1907-1981)
1965%Sin-Itiro Tomonaga(1906-1979)
1968%Yasunari Kawabata(1899-1972)
1973%Reona Esaki(Leo Esaki)(1925-)
1974%Eisaku Sato(1901-1975)
1981%Kenichi Fukui(1918-1998)
1987%Susumu Tonegawa(1939-)
1994%Kenzaburo Oe(1935-)
2000%Hideki Shirakawa(1936-)

 

なお、アウトプットのデリミタの文字数は2文字以上でもOKです。「%」と文字列の間に空白文字を足してみます。

 

$ cut -d "/" -f 1-2 nobel.txt --output-delimiter=" % "

1949 % Hideki Yukawa(1907-1981)
1965 % Sin-Itiro Tomonaga(1906-1979)
1968 % Yasunari Kawabata(1899-1972)
1973 % Reona Esaki(Leo Esaki)(1925-)
1974 % Eisaku Sato(1901-1975)
1981 % Kenichi Fukui(1918-1998)
1987 % Susumu Tonegawa(1939-)
1994 % Kenzaburo Oe(1935-)
2000 % Hideki Shirakawa(1936-)

 


cutコマンドはオプションの種類がそんなに多くないのでsedコマンドよりは慣れやすいと思います。cutもsedも便利なコマンドですので、適材適所で使ってあげましょう。

 

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です