[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

コンピュータIID(UNIXとHTML)第4回

目次
4.1 パイプ
4.1.1 道具の組み合わせ
4.1.2 パイプとは
4.1.3 フィルタ
4.1.4 パイプの使用例
4.2 演習4
4.3 レポート課題
4.4 参考文献
索引

4.1 パイプ

4.1.1 道具の組み合わせ

これまで、sortで整列したり、grepで探索したりと、色々なコマンドを利用してきました。 しかし、どれもこれも、ちょっとしたことしかできません。 こんなもので、本当に役に立つのでしょうか。

UNIXでは、小さな道具を組み合わせて本格的な道具にする、という考え方をします。 つまり、多機能のコマンドを大量に用意するのではなく、単機能のコマンドをある程度用意し、必要に応じてそれらを組み合わせるのです。 利用者の工夫次第で、いくらでも便利な道具が作り出せるわけです。

例えば、テキスト・ファイルの5行目を表示したいとします。 このとき、5行目を表示するようなコマンドを用意する必要はありません。 最初の5行を取り出してから、最後の1行を表示すれば、5行目は表示されます。 したがって、最初の数行を表示するheadコマンドと、最後の数行を表示するtailコマンドを組み合わせればよいのです。

4.1.2 パイプとは

パイプ とは、順番にデータを入れると、そのままの順番でデータが出てくる仕組みです。 管の中をデータが流れている様子を想像してください。 パイプを使えば、コマンドを組み合わせることができます。

UNIXシェルでは、記号"|"がパイプを表します。 パイプの形式は

command1|command2

です。 このコマンドを入力しますと、まず、コマンド command1 が実行されます。 その結果は画面には表示されず、パイプに入ります。 そして、そのままパイプから出てきて、それに対して command2 が実行されます。 最終結果は画面に表示されます。

パイプは何段階も使えます。 2段階ですと、

command1|command2|command3

となります。 コマンド command1 が実行され、パイプを通り、その結果に対して command2 が実行され、パイプを通り、その結果に対して command3 が実行されます。 まるで、コマンドとコマンドを結ぶ管の中を、データが流れていくようなものです。

最初の例の、5行目を表示するコマンドは、次のようになります。

b04a001@AsiaA1:~% cd comp2d
b04a001@AsiaA1:~/comp2d% cat month01.txt
January
February
March
April
May
June
July
August
September
October
November
December
b04a001@AsiaA1:~/comp2d% head -5 month01.txt
January
February
March
April
May
b04a001@AsiaA1:~/comp2d% head -5 month01.txt | tail -1
May
b04a001@AsiaA1:~/comp2d%

ここで、tailコマンドに引数がないことに注意してください。 もともと、tailコマンドは、引数のファイルからデータを読み込み、その最後の数行を表示するものです。 ここでは、引数ではなく、パイプからデータを読み込みます。 したがって、引数を書かないのです。

パイプを利用する場合、多くのコマンドでは、引数を書けばそのファイルからデータを読み込み、引数を書かなければパイプからデータを読み込みます。

次の例は、探索件数を数えるものです。 これは、文字列を探索するgrepコマンドと、行数を数えるwcコマンドを組み合わせればできます。 以下では、晴れ(Fine)の日が何日あるかを求めています。

b04a001@AsiaA1:~/comp2d% cat weather01.txt
October 1 Sunday Cloudy
October 2 Monday Fine
October 3 Tuesday Cloudy
October 4 Wednesday Cloudy
October 5 Thursday Rainy
October 6 Friday Rainy
October 7 Saturday Fine
b04a001@AsiaA1:~/comp2d% grep Fine weather01.txt
October 2 Monday Fine
October 7 Saturday Fine
b04a001@AsiaA1:~/comp2d% grep Fine weather01.txt | wc
       2       8      46

4.1.3 フィルタ

ここで、以下の内容をファイルenglish01.txtに保存します。

This is a pen.
Is this a pen?
Yes, it is.

コマンドの中には、引数でファイルが指定できず、専らパイプからデータを読み込むものがあります。 そのようなコマンドを フィルタ と呼びます。 引数でファイルが指定できても、普通はパイプからデータを読み込むなら、フィルタと呼ぶことが多いです。

trコマンド (TRanslate)は、文字を置き換えたり削除したりするフィルタ・コマンドです。 置き換える場合の形式は

tr string1 string2

です。 これで、 string1 の1文字目が string2 の1文字目に置き換えられ、 string1 の2文字目が string2 の2文字目に置き換えられ、…となります。

例えば、アルファベットをすべて大文字にするには、

tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ

とします。 もちろん、これでは大変なので

tr a-z A-Z

と省略できます。

b04a001@AsiaA1:~/comp2d% cat english01.txt
This is a pen.
Is this a pen?
Yes, it is.
b04a001@AsiaA1:~/comp2d% cat english01.txt | tr a-z A-Z
THIS IS A PEN.
IS THIS A PEN?
YES, IT IS.
b04a001@AsiaA1:~/comp2d%

テキスト・ファイルのスペースを改行に置き換えれば、一行に一単語という、バラバラの状態になります。 このような目的にも、trコマンドが使えます。 改行を直接書くことはできませんが、"\n"と書きますと、改行を意味します。 スペースも"\n"も、シングルクオートで囲みます。

b04a001@AsiaA1:~/comp2d% cat english01.txt | tr ' ' '\n'
This
is
a
pen.
Is
this
a
pen?
Yes,
it
is.
b04a001@AsiaA1:~/comp2d%

trコマンドの、削除する場合の形式は

tr -d string

です。 これで、 string の中の文字が削除されます。

以下では、句読点を取り除いています。

b04a001@AsiaA1:~/comp2d% cat english01.txt | tr -d '.,?'
This is a pen
Is this a pen
Yes it is
b04a001@AsiaA1:~/comp2d%

uniqコマンド (UNIQue)は、同じ行が連続しているとき、それらを一つにまとめます。 形式は

uniq file

です。

uniqコマンドは、普通はsortコマンドと一緒に使います。 同じ行があちこちにあるファイルは、sortで整列しますと、同じ行は一か所に固まります。 そして、uniqでフィルタをかけますと、一つになります。

以下では、天気の種類を求めています。

b04a001@AsiaA1:~/comp2d% cat weather01.txt
October 1 Sunday Cloudy
October 2 Monday Fine
October 3 Tuesday Cloudy
October 4 Wednesday Cloudy
October 5 Thursday Rainy
October 6 Friday Rainy
October 7 Saturday Fine
b04a001@AsiaA1:~/comp2d% awk '{print $4}' weather01.txt
Cloudy
Fine
Cloudy
Cloudy
Rainy
Rainy
Fine
b04a001@AsiaA1:~/comp2d% awk '{print $4}' weather01.txt | sort
Cloudy
Cloudy
Cloudy
Fine
Fine
Rainy
Rainy
b04a001@AsiaA1:~/comp2d% awk '{print $4}' weather01.txt | sort | uniq
Cloudy
Fine
Rainy
b04a001@AsiaA1:~/comp2d%

uniqコマンドでは、何行連続しているかも求められます。 形式は

uniq -c file

です。

以下では、天気の種類ごとの日数を求めています。

b04a001@AsiaA1:~/comp2d% awk '{print $4}' weather01.txt | sort
Cloudy
Cloudy
Cloudy
Fine
Fine
Rainy
Rainy
b04a001@AsiaA1:~/comp2d% awk '{print $4}' weather01.txt | sort | uniq -c
   3 Cloudy
   2 Fine
   2 Rainy
b04a001@AsiaA1:~/comp2d%

4.1.4 パイプの使用例

ここでは、例題として、英文テキストに単語が何種類使われているかを調べます。 注意点は、"This"と"this"は同じ単語であることです。 ただし、話を簡単にするために、"pen"と"pens"は違う単語とします。 以下のような手順でテキスト処理を行えば、答えが出てきます。

  1. 句読点を取り除く。
  2. アルファベットを小文字にする。
  3. 一行に一単語となるようにする。
  4. 整列する。
  5. 重複を取り除く。
  6. 行数を数える。
b04a001@AsiaA1:~/comp2d% cat english01.txt
This is a pen.
Is this a pen?
Yes, it is.
b04a001@AsiaA1:~/comp2d% cat english01.txt | tr -d '.,?'
This is a pen
Is this a pen
Yes it is
b04a001@AsiaA1:~/comp2d% cat english01.txt | tr -d '.,?' | tr A-Z a-z
this is a pen
is this a pen
yes it is
b04a001@AsiaA1:~/comp2d% cat english01.txt | tr -d '.,?' | tr A-Z a-z | tr ' ' '\n'
this
is
a
pen
is
this
a
pen
yes
it
is
b04a001@AsiaA1:~/comp2d% cat english01.txt | tr -d '.,?' | tr A-Z a-z | tr ' ' '\n' | sort
a
a
is
is
is
it
pen
pen
this
this
yes
b04a001@AsiaA1:~/comp2d% cat english01.txt | tr -d '.,?' | tr A-Z a-z | tr ' ' '\n' | sort | uniq
a
is
it
pen
this
yes
b04a001@AsiaA1:~/comp2d% cat english01.txt | tr -d '.,?' | tr A-Z a-z | tr ' ' '\n' | sort | uniq | wc
       6       6      21
b04a001@AsiaA1:~/comp2d%

結局、6種類の単語が使われたことが分かります。


4.2 演習4

コマンドを使って、ファイルenglish01.txtの中では、どの単語が何回使われいるかを求めてください。

b04a001@AsiaA1:~/comp2d% ???
   2 a
   3 is
   1 it
   2 pen
   2 this
   1 yes

余力のある人は、オリジナルの英文テキスト(数行でよい)をファイル(例えばenglish02.txt)に保存し、コマンドを使って、どの単語が何回使われいるかを求めてください。


4.3 レポート課題

今日の演習4の答案(「ターミナル」画面のコピー)をメールでkonishi@twcu.ac.jp宛に提出してください。 メールを送るときは、大学のパソコンを使うか、大学のメール・サーバに接続するかして、差出人が大学のメール・アドレスになるようにしてください。 メールの本文には、学生番号、氏名、科目名、授業日(10月18日)を明記してください。


4.4 参考文献


[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

2006年10月18日更新
小西 善二郎 <konishi@twcu.ac.jp>
Copyright (C) 2006 Zenjiro Konishi. All rights reserved.