YUKIPON Linuxコマンド集
過去にリンクを貼らせて頂いていたサイトがなくなりましたので、保存していた内容をUPさせていただきました。
作者の方で、新アドレスになさっていた場合、ご連絡いただければ元のリンク状態に戻しますし、こちらでの表示が不適切であるとご判断の節はご連絡くだされば削除させていただきます。
このドキュメントは Slackware + PJE をベ−スに書かれたものなので、プロンプトの表示やディレクトリ名など、一部 Vine Linux と食い違っている部分があります。あらかじめご了承ください。
<<目次>>
@ディレクトリの移動と表示 cdコマンド、lsコマンド
Aシェルのユーザー補助機能 ファイル名の補完、 コマンドの実行履歴
Bファイル操作コマンド cp コマンド、mv コマンド、rm コマンド、ln -s コマンド
Cディレクトリ操作コマンド mkdir コマンド、rmdir コマンド、cp -R コマンド、rm -R コマンド
Dアクセス権の変更 chmod コマンド
Eオンライン マニュアル man コマンド
F標準入力・標準出力の変更 リダイレクション、パイプライン
Gテキスト処理コマンド grep コマンド、sort コマンド、uniq コマンド
  grep、sort、uniq を組み合わせた利用例 awk コマンド
Hシェル スクリプト
1. ディレクトリの移動と表示
まず初めに、ハードディスクの中を自由に移動して、内容を確認する方法を説明します。 Linux を起動したら root 以外の (一般の) ユーザーでログインしてください。
cd コマンド
まずは他のディレクトリに移動してみましょう。 ディレクトリを移動するコマンドは cd です。
hostname:~$  cd  /usr/local/bin

hostname:/usr/local/bin$ 
プロンプトが変わりました。 これで /usr/local/bin に移動した事がわかります。ここから更に /usr/local/lib に移動するには、いくつかの方法が考えられます。以下のどれでも結果は同じです。
hostname:/usr/local/bin$  cd  ..                ←─ 2 回に分けて移動

hostname:/usr/local$      cd  lib

hostname:/usr/local/lib$



hostname:/usr/local/bin$  cd  ../lib            ←─ 相対パスを指定して移動

hostname:/usr/local/lib$



hostname:/usr/local/bin$  cd  /usr/local/lib    ←─ 絶対パスを指定して移動

hostname:/usr/local/lib$
移動先を指定しないで cd コマンドを実行すると、ホーム ディレクトリに戻ります。
hostname:/usr/local/lib$  cd

hostname:~$

ls コマンド
では、ホーム ディレクトリに戻って、その内容を表示してみましょう。 ディレクトリの内容を表示するコマンドは ls (エルとエス、どちらも小文字) です。
hostname:~$  ls

bin
インストールした直後なら、おそらく bin しか表示されないと思います。これから色々なファイルを作っていけば、表示される内容が増えていきます。

さて、しかし本当に bin だけしかないのでしょうか? 少なくとも、いくつかの設定ファイルは存在するはずです。実は、ls コマンドは . (ピリオド) で始まるファイル名を表示しません。 DOS には隠しファイルという属性がありますが、Linux では . で始まるファイルは自動的に隠しファイルになるわけです。設定ファイルは普段は表示する必要がないため、どれも . で始まるファイル名になっています。これらのファイルを表示するには、-a (All files の意味) を付けて ls を実行します。

hostname:~$  ls -a

.           .Xmodmap    .fvwm2rc    .lessrc     .vimrc      bin

..          .bashrc     .inputrc    .profile    .xinitrc

.Xdefaults  .canna      .less       .tkdesk     .xsession
.Xdefaults、.Xmodmap、.profile、等が設定ファイルです。
ここで注意しなければならないのは、. (ピリオド 1 つ)、..(ピリオド 2 つ)、.tkdesk、 bin の 4 つは実はファイルではなく、ディレクトリだという点です。 (. はカレントディレクトリ、.. は親ディレクトリを表しています。) この表示ではファイルとディレクトリの区別がつかないので、種類がわかるようにするオプションが -F (File type の意味、F は大文字) です。
hostname:~$  ls -a -F

./          .Xmodmap    .fvwm2rc    .lessrc     .vimrc      bin/

../         .bashrc     .inputrc    .profile    .xinitrc

.Xdefaults  .canna      .less       .tkdesk/    .xsession*
このように -F をつけると、ディレクトリ名の後に / が表示されます。 それ以外にも、実行可能ファイルには *、シンボリック リンクには @ が表示されます。
余談ですが、ここで ls -a -F と入力するかわりに、以下のように ls -aF としても結果は同じです。 ほとんどの Linux コマンドでは、一つの - (ハイフン) の後に複数のオプションを続けて指定できます。
hostname:~$  ls -aF

./          .Xmodmap    .fvwm2rc    .lessrc     .vimrc      bin/

../         .bashrc     .inputrc    .profile    .xinitrc

.Xdefaults  .canna      .less       .tkdesk/    .xsession*
これでファイルやディレクトリの一覧を表示できるようになりましたが、 これだけではファイルのサイズや日付がわかりません。このような詳細情報を表示するには -l (小文字のエル、Long format の意味) オプションを使います。
hostname:~$  ls -a -l   (または ls -al)

total 29

drwxr-xr-x   4 kasahara users        1024 Jan  4 11:46 .

drwxr-xr-x  12 root     root         3072 Jan 15 10:12 ..

-rw-r--r--   1 kasahara users        1741 Dec 19 00:00 .Xdefaults

-rw-r--r--   1 kasahara users          23 Dec 19 00:00 .Xmodmap

-rw-r--r--   1 kasahara users         149 Dec 19 00:00 .bashrc

-rw-r--r--   1 kasahara users        5345 Dec 19 00:00 .canna

-rw-r--r--   1 kasahara users        5352 Dec 19 00:00 .fvwm2rc

-rw-r--r--   1 kasahara users          57 Dec 19 00:00 .inputrc

-rw-r--r--   1 kasahara users          34 Nov 24  1993 .less

-rw-r--r--   1 kasahara users         114 Nov 24  1993 .lessrc

-rw-r--r--   1 kasahara users         475 Dec 19 00:00 .profile

drwxr-xr-x   3 kasahara users        1024 Dec 19 00:00 .tkdesk

-rw-r--r--   1 kasahara users          28 Dec 19 00:00 .vimrc

-rw-r--r--   1 kasahara users         267 Dec 19 00:00 .xinitrc

-rwxr-xr-x   1 kasahara users         258 Dec 19 00:00 .xsession

drwxr-xr-x   2 kasahara users        1024 Dec 19 00:00 bin



    ↑            ↑     ↑           ↑        ↑        ↑

    │            │     │           │        │        │

    │          所有者   │         サイズ   修正日付      │

    │                グループ    (バイト数)          ファイル名

    │

    └─ ファイルの種類とアクセス権
ls コマンドでは、カレント ディレクトリ以外にも、指定したディレクトリの内容を表示することができます。 ls の後にディレクトリ名を指定するだけです。例えば /usr/openwin/bin の内容を表示するには、
hostname:~$  ls  /usr/openwin/bin

clock      msgfmt     olwmslave  props      svenv      winsysck   xgettext

cmdtool    olvwm      openwin    shelltool  textedit   workman

meminfo    olwm       owplaces   sunview    toolwait   xcenter
のようにします。 また、ファイルの詳細を表示するには、-l オプションをディレクトリ名の前に指定します。
hostname:~$  ls -l  /usr/openwin/bin

total 763

-rwxr-xr-x   1 root     root        24732 May 30  1996 clock

-rwxr-xr-x   1 root     root        13124 May 30  1996 cmdtool

-rwxr-xr-x   1 root     bin         12440 Jul 28  1995 meminfo

-rwxr-xr-x   1 root     root         7132 May 30  1996 msgfmt

-rwxr-xr-x   1 root     root       296300 Jun  5  1996 olvwm

-rwxr-xr-x   1 root     root       182144 May 30  1996 olwm

-rwxr-xr-x   1 root     root        21788 May 30  1996 olwmslave

-rwxr-xr-x   1 root     root         1350 May 30  1996 openwin

-rwxr-xr-x   1 root     root          111 May 30  1996 owplaces

-rwxr-xr-x   1 root     root        37240 May 30  1996 props

lrwxrwxrwx   1 root     root            7 Jan  4 20:19 shelltool -> cmdtool

drwxr-xr-x   2 root     root         1024 May 30  1996 sunview

-rwxr-xr-x   1 root     bin           154 Oct 17  1994 svenv

-rwxr-xr-x   1 root     root        16040 May 30  1996 textedit

-rwxr-xr-x   1 root     bin            21 Oct 17  1994 toolwait

-rwxr-xr-x   1 root     bin           503 Oct 17  1994 winsysck

-rwxr-xr-x   1 root     bin        119259 Oct 20 15:23 workman

-rwxr-xr-x   1 root     root        10564 May 30  1996 xcenter

-rwxr-xr-x   1 root     root        14840 May 30  1996 xgettext

ここで注目してほしいのは、shelltool は実はシンボリック リンクで、 cmdtool を参照しているというのが一目でわかる点です。 シンボリック リンクの参照先も ls -l で確認できるわけです。

このページトップ目次へ
2. シェルのユーザー補助機能.
シェル (bash) は、ユーザーが入力したコマンドを解釈して実行するプログラムです。ユーザーがコンソールでログインした時や、kterm が実行された時に、 自動的にシェルが起動してユーザーのコマンド入力を待ちます。 (kterm がコマンドを認識しているのではなく、 kterm の中で動作しているシェルがコマンドを解釈していることに注意してください。) コマンド プロンプトを表示しているのもシェルです。
このシェルには、コマンド入力を手助けする便利な機能が沢山あります。

ファイル名の補完
ls でディレクトリ名を確認し cd で移動先を指定すれば、 ハードディスク上のどこへでも移動できます。しかし実際には、完全なディレクトリ名を知らなくても操作可能です。 先頭の数文字だけ入力すれば、残りをシェルに補完させる事ができるからです。
次の例を見てください。
hostname:~$  cd  /u
ここで [Tab] キーを押すと、自動的に次のように補完されます。
hostname:~$  cd  /usr/
これは、シェルが次のように状況判断するからです。
  • ルート ディレクトリ内に u で始まるファイルやディレクトリは usr しかないため、 u が入力された時点で usr を決定できる。
  • /usr はディレクトリなので、最後に / が付加される。
では、続けて、
hostname:~$  cd  /usr/l
のように l (エル) を入力して [Tab] キーを押してみましょう。 今度はブザーが鳴り、補完されません。これは何故かというと、 /usr ディレクトリに l で始まるディレクトリは lib、libexec、local の 3 つが存在するので、 先頭の l だけでは決定できなかったためです。 ここで、もう一度 [Tab] キーを押すと、現在考えられる候補の一覧が表示されます。
hostname:~$  cd  /usr/l     ←─ [Tab] キーをもう一度押します。

lib      libexec  local    

hostname:~$  cd  /usr/l
例えば /usr/local を指定したい場合なら、次に o を入力すれば決定することがわかります。 o を入力して [Tab] キーを押すと、期待通り次のように補完されます。
hostname:~$  cd  /usr/local/
この機能は cd 以外のコマンドでも有効です。 例えば、ls コマンドで /usr/local/bin/jcommunicator の詳細を表示したい時は、
hostname:~$  ls -l  /usr/local/bin/jcommunicator
と入力しなければならないのですが、補完機能を使えば、 [L] [S] [スペース] [-] [L] [スペース] [/] [U] [Tab] [L] [O] [Tab] [B] [Tab] [J] [C] [Tab] とキー入力するだけで済みます。 全て入力した場合 34 回キーを叩かなければならないところが、17 回で済みました。 また、コンピュータが補完しているのですから、打ち間違いもありません。

補完機能を使えば、キーボードの苦手な方でも比較的容易にコマンドライン操作ができます。このフィーリングをつかんで、自然に [Tab] キーを押せるようになってください。


コマンドの実行履歴
コマンドの入力を補助するツールとしては、補完機能の他に履歴機能があります。

シェルは過去に実行したコマンドを記憶していて、[↑] キーが押されるたびにそれらを順番に表示します。もう一度実行したいコマンドが表示されたら、[Enter] キーを押して実行できます。コマンドラインの一部を修正したい場合は、[←]、[→] キーでカーソルを移動して修正できます。

このページトップ目次へ
3. ファイル操作コマンド
この章では、基本的なファイル操作のコマンドを紹介します。

cp コマンド
ファイルのコピーには cp コマンドを使います。
hostname:~$  cp  file_1  file_2
この例では、カレント ディレクトリの file_1 を、file_2 というファイル名でコピーします。
余談ですが、Linux の世界でファイルに名前をつける時は、 単語の切れ目にスペース (0x20) を使わず _ (アンダースコア) を使用するのが普通です。 ファイル名にスペースを使っても動作上の問題はありませんが、コマンドラインに入力する時にファイル名全体を " " で括る必要があるので面倒です。
本題に戻って、上の例の file_2 の部分をディレクトリ名に変えると、 そのディレクトリの中に file_1 がコピーされます。 この場合ファイル名は変更されません。
hostname:~$  cp  file_1  /tmp/     ←─ /tmp/ にコピー

hostname:~$  cp  file_1  ..        ←─ 親ディレクトリにコピー
このようにコピー先がディレクトリの場合は、 コピー元のファイルを複数指定して一気にコピーすることができます。
hostname:~$  cp  file_1  file_2  file_3  /tmp/

ここで便利に使えるのがシェルのワイルドカード機能なので、ついでに説明します。

上の例の場合、コピーするファイルは全て file_ で始まっているので、 「file_ で始まるファイルを全てコピー」 と指示できれば楽です。 Linux ではこれを次のように表現します。
hostname:~$  cp  file_*  /tmp/
file_* という条件に合致するファイルが全て選択されます。 * は、どのような文字列にも (あるいは文字列が存在しない場合にも) すべてマッチする記号なので、file_1、file_2、file_work、file_LINUX などの全てが選択されます。 Linux のシェルでは、以下のパターン記号が使えます。
* どのような文字列にもマッチします。 文字列が存在しない場合にもマッチします。 (ただし、ピリオドで始まる隠しファイルとマッチさせるには、 .k* のように先頭にピリオドを付ける必要があります。) 
*file* の場合
  • file, file11, abc_file, linux_file_test → OK
  • File, fi_le11 → NG
? 1 つの文字とマッチします。 どの文字でも構いませんが、1 文字でなければなりません。文字が存在しない場合はマッチしません。 
?file? の場合
  • 1file2, _file_, ffilee → OK
  • file, file2, 1file22 → NG
[...] [ ] で括られた文字のうちの、どれか一つとマッチします。 - (ハイフン) を使うと、文字の範囲を指定できます。
file[123] の場合
  • file1, file2, file3 → OK
  • file, file4, 1file, file33 → NG
file[a-e] の場合
  • filea, fileb, filee → OK
  • filef, filez, fileA, fileE → NG
[!...] [! ] で括られた文字以外の 1 文字とマッチします。 
file[!123] の場合
  • file4, filea, fileZ → OK
  • file1, file2, file444, fileabc → NG
これらを組み合わせて、file[a-c][!1-3]*.tar.? のように記述することもできます。
重要
これらのパターン記号は cp 等のコマンドによって解釈されるのではなく、 シェルが展開した結果がコマンドに渡されます。
例えば最初の例で、
hostname:~$  cp  file_*  /tmp/
とした場合、cp コマンドに渡される引数は、
file_1  file_2  file_3  /tmp/

です。 (file_* /tmp/ がそのまま渡されるわけではありません。) これを理解していないと思わぬ結果になる可能性がある事は、 mv コマンドのところで説明します。


mv コマンド
ファイル名の変更とファイルの移動には mv コマンドを使います。
hostname:~$  mv  file_1  file_2
この例では、file_1 のファイル名が file_2 に変わります。 mv コマンドではさらに、
hostname:~$  mv  file_1  /tmp/file_2
のようにファイルを別のディレクトリに移動することもできます。 cp コマンドと同様、移動先にディレクトリを指定した場合は移動元ファイルを複数指定できます。
hostname:~$  mv  file_1  file_2  file_3  /tmp/
ワイルドカードを使えば、次のようになります。
hostname:~$  mv  file_[123]  /tmp/
注意
ワイルドカードを使う時は、移動先のディレクトリを指定する事を絶対に忘れないでください。例えば、ディレクトリに alabama と amazon という 2 つのファイルだけが存在する時、これらを 親ディレクトリに移動するコマンド  
hostname:~/work/africa$  mv  a*  ../
を実行する時、移動先の ../ を指定し忘れて、
hostname:~/work/africa$  mv  a*
のように実行してしまうと最悪です。 ワイルドカードはシェルが展開しますから、実際に実行されるコマンドは次のようになります。
mv  alabama  amazon
これは、つまり alabama を amazon に移動するコマンドなので、amazon が alabama によって上書きされてしまいます。 このような事故を防ぐには、mv コマンドに -i オプションを付ける方法もあります。 そうすれば、移動先にファイルが存在する場合は、
hostname:~/work/africa$  mv -i  a*

mv: replace `amazon'? 

のように確認を求められます。


rm コマンド
ファイルの削除には rm コマンドを使います。
hostname:~$  rm  file_1
この例では file_1 が削除されます。 一度 rm で削除したファイルは、復旧することができませんから注意してください。
次のように、複数のファイルを同時に削除することもできます。
hostname:~$  rm  file_1  file_2  file_3

hostname:~$  rm  file_*

ln -s コマンド
シンボリック リンクを作成するには ln -s コマンドを使います。 -s オプションを付けずに ln だけで実行すると、 シンボリック リンクではなく通常のリンク (ハードリンク) を作成できるのですが、 話が複雑になるのでハードリンクの説明はしません。
hostname:~$  ln -s  /usr/local/bin/gs  gs
この例では、/usr/local/bin/gs へのシンボリック リンクがカレント ディレクトリに作成されます。 シンボリック リンクは参照先のファイルと同じように扱えますから、 ./gs を実行すれば透過的に /usr/local/bin/gs を実行できます。
hostname:~$  ln -s  /usr/local/bin/  loc_bin
このようにディレクトリへのリンクを作成すれば、ディレクトリとして扱えます。ここで、
hostname:~$  cd  loc_bin

とすれば、/usr/local/bin/ に移動できます。

シンボリック リンクに対する cp、mv、rm の操作は、次のように扱われます。
cp リンクの参照先のファイルがコピーされます。 つまり、ファイルが 2 つになるのであって、リンクが 2 つになるわけではありません。 シンボリック リンク 「そのもの」 をコピーする時は、-d オプションを付けます。 
mv シンボリック リンクを移動します。 元のファイルには影響しません。 ただし、別のパーティションや別のディスクには移動できません。 
rm シンボリック リンクを削除します。 元のファイルには影響しません。 
このページトップ目次へ
4. ディレクトリ操作コマンド
この章では、基本的なディレクトリ操作のコマンドについて説明します。

mkdir コマンド
ディレクトリを作成するには mkdir コマンドを使います。
hostname:~$  mkdir  directory1
この例では、directory1 という名前のディレクトリを作成します。 パスを指定すれば、カレントディレクトリ以外の場所にもディレクトリを作れます。
hostname:~$  mkdir  /tmp/work_dir

ただし、存在しないディレクトリの子ディレクトリは作れません。 作成するディレクトリの親ディレクトリは、あらかじめ作っておく必要があります。


rmdir コマンド
ディレクトリを削除するには rmdir コマンドを使います。
hostname:~$  rmdir  directory1
ただし、削除するディレクトリは空になっている必要があります。 ファイルや他のディレクトリを含むディレクトリを rmdir で削除しようとすると、
rmdir: directory1: Directory not empty
というエラーが表示されます。 特に、ピリオドで始まる隠しファイルの存在には気付かない場合もありますから注意してください。

cp -R コマンド
コピーのコマンド cp に -R オプションを付けると、ディレクトリ全体を (サブディレクトリまで) コピーできます。
hostname:~$  cp -R  /usr/doc/JF/  .
この例では、/usr/doc/JF/ がカレント ディレクトリにコピーされます。 カレントディレクトリに JF ディレクトリが作成され、その内容がコピーされます。

rm -R コマンド
削除のコマンド rm も、-R オプションを付けるとディレクトリ全体を削除できます。ファイルを全部削除してから rmdir コマンドを使うのは面倒なので、 rm -R で一気に削除する方が便利です。 (ただし危険性も高いですが。)
hostname:~$  rm -R  JF/
このようにすると、JF ディレクトリが中身まで全て削除されます。
このページトップ目次へ
5. アクセス権の変更
ここではファイルのアクセス権を変更するコマンドについて簡単に説明しておきます。

chmod コマンド
ファイルのアクセス権を表す例の 9 文字 (rwxr-xr-- のようなもの) は、 chmod コマンドで変更できます。
このコマンドではファイルの所有者 (オーナー) を u 、グループを g 、その他のユーザーを o という文字で表し、それぞれに読み取り r 、書き込み w 、実行 x の中から許可する権利を 設定するようになっています。例えば、オーナーのみ読み書き可能で、 それ以外のユーザーは全くアクセスできないファイルにする場合、次のように実行します。
$  chmod  u=rw  file1

$  chmod  go=   file1
ls -l で表示すると、アクセス権が -rw------- になっている事が確認できます。他人に見られたくないファイルは、このように設定すれば良いわけです。
また、本当は実行可能ファイルなのに実行可能になっていない場合は、
$  chmod  ugo+x  file2

のようにすれば、すべてのユーザーが実行できるようになります。

u=rw のように = を使った場合、指定していないアクセス権 (この場合 x ) は 無効になりますが、ugo+x のように + を使った場合、指定していないアクセス権 (この場合 r と w ) は変化しません。 + の反対に、特定のアクセス権だけ無効にする場合は、- を使って次のようにします。
$  chmod  o-x  file3
この例では、オーナーでなくグループも違うユーザーは file3 を実行できなくなります。 o の実行可能属性以外は変化しません。
このページトップ目次へ
6. オンライン マニュアル

man コマンド
Linux のほとんどのコマンドにはオンライン マニュアルが付属しています。 これらは man コマンドで見ることができます。 マニュアルの内容は less を使って表示されるので、 [↑]、[↓]、[Page Up]、[Page Down] キーでスクロールし、 [Q] キーで終了できます。
ところが、一つ問題なのは、ほとんどのマニュアルが英文なのです。 「英語はちょっと...」という方も少なくないでしょうから (私も含めてですが)、ここで man を見るときのコツをご紹介します。
例として、ls のマニュアルを表示してみます。
$  man  ls

マニュアルはいくつかのセクションにわかれていて、その構成はどのコマンドでもほぼ共通です。ですから大体の構成を覚えておけば、 全部を読まなくても必要な情報を見つけやすくなります。

どのコマンドのマニュアルでも最初に書いてあるのが SYNOPSIS です。これはコマンドの構文を表していますから、 エラーが発生してコマンドを実行できない時はチェックしましょう。

次に DESCRPTION があって、コマンドの動作の詳細が説明されています。何をするコマンドなのか全くわからない時は、ここをチェックします。

オンライン マニュアルの中で一番見る機会が多く、しかも重要なのは OPTIONS セクションだと思います。 コマンドラインにどのオプションを指定した時に、どのように動作するかという事が一覧形式で書いてあります。 何か具体的にやりたい事がある時は、ここをチェックします。目的なくこのセクションを読むだけでも、コマンドの多彩な機能がわかって面白いです。 (GNU のツールの場合、POSIX OPTIONSGNU OPTIONS が分けて書いてありますが、どちらも使えます。)

あとは、BUGSNOTES 等のセクションが続きます。 SEE ALSO には関連するコマンドの一覧が載っていますので、 それらのコマンドのマニュアルを参照すれば、さらに参考になるかもしれません。
このページトップ目次へ
7. 標準入力・標準出力の変更
ここからが Linux コマンドの面白くなってくるところです。 コマンドの出力をファイルに保存したり、他のコマンドに渡したりする方法について説明します。

リダイレクション
kterm などのターミナルで Linux コマンドを実行した場合、 その出力はターミナル上に表示されます。これは、コマンドの標準出力 (ファイル ディスクリプタ = 1) が ターミナルに接続されているからです。普通に Linux コマンドを実行した場合、次の 3 つの入出力がターミナルに接続されます。
  • 標準入力 : ファイル ディスクリプタ = 0
  • 標準出力 : ファイル ディスクリプタ = 1
  • エラー出力 : ファイル ディスクリプタ = 2
つまりキーボードから入力した文字列が標準入力に送られ、 標準出力やエラー出力された文字列はターミナルに表示されます。
標準入力されたデータを標準出力するだけのコマンド cat を使って、この動作を確認してみましょう。
$  cat
cat を実行すると、何も表示されず、そのまま止まってしまったと思います。この状態では、cat は標準入力からのデータを待っています。 つまり、キーボードからの入力を待っているわけです。では、何かをキーボードで入力してみましょう。
$  cat

Do the best at Yokohama Arena     ←─ この行を入力して [Enter] キーを押します。

Do the best at Yokohama Arena
1 行目を入力して [Enter] キーを押すと、同じ内容が 2 行目に表示されたと思います。キーボードからの標準入力が、ターミナル画面に標準出力されたわけです。 cat コマンドはこれを延々繰り返します。 終了するには、ファイルの終了 (End of File = EOF) を表す [Ctrl] + [D] を押します。
同じ例を使って、今度は標準出力をファイルに書き込んでみましょう。 標準出力をファイルに書き込むには、記号 > を使います。
$  cat  > out_file

Do the best at Yokohama Arena

   ←─ ここで [Ctrl] + [D] を押します。

$
画面上に同じ内容が表示されません。 その出力は out_file に入ってしまったからです。
今度は、今作ったファイルを標準入力に送って画面に表示してみましょう。標準入力を変更するには、記号 < を使います。
$  cat  < out_file

Do the best at Yokohama Arena
前の例で作成した out_file が標準入力から読み込まれ、標準出力のターミナルに表示されました。これらを組み合わせて使うこともできます。
$  cat  < out_file  > out_file2
このコマンドでは、out_file を読み込んで out_file2 に書き込みます。 つまり、
$  cp  out_file  out_file2
と同じ結果になります。
それでは、エラー出力はどうなっているのでしょうか。 mv コマンドを使って、わざとエラーを発生させて確かめてみます。
$  mv  abc

mv: missing file argument

Try `mv --help' for more information.
mv コマンドにファイル名を 1 つしか指定しないと、このようなエラーが発生します。前の例のように標準出力をファイルに出力すると、どのように変わるでしょうか。
$  mv  abc  > out_file

mv: missing file argument

Try `mv --help' for more information.
何も変わりません。 ちなみに out_file には何も出力されないので、サイズが 0 バイトになります。 エラー出力の出力先は、別に指定しなければいけないわけです。標準出力以外の出力をファイルに書き出すには、記号 > の前にファイルディスクリプタを付けて指定します。 エラー出力のファイル ディスクリプタは 2 ですから、次のようになります。
$  mv  abc  2> err_file
今度は出力が err_file に保存されました。 もし標準入力、標準出力とエラー出力に別々のファイルを指定したい場合は、 <>2> を組み合わせて使えます。
$  cat  < in_file  > out_file  2> err_file
注意
ただし in_file がない時にこのコマンドを実行すると、 No such file or directory エラーがターミナルに表示されます。 (err_file に入りません。) これは cat のエラー出力ではなく、bash のエラーだからです。
標準出力とエラー出力を同じファイルに書き込みたい場合はどうすればよいでしょうか? その時は、記号 &> を使います。
$  cat  &> out_file
こうすると、両方の出力が out_file に書き込まれます。

パイプライン
一つのコマンドの標準出力を、別のコマンドの標準入力に接続することもできます。コマンドラインに 2 つのコマンドを並べて書き、 その間を記号 | で区切っておくと、前に書いたコマンドの標準出力が後のコマンドの標準入力に接続されます。 次の例を見てください。
$  ls /var  |  cat

X11R6

adm

games

lib

lock

locks

log

man

news

openwin

pid

preserve

run

rwho

spool

tmp

yp

普通に ls を実行するのと変わらないようにも見えますが、 実際は ls の出力が cat を経由してターミナルに出力されています。 ちなみに ls コマンドは、出力先がターミナルでない場合、このようにファイル名を 1 つずつ改行で区切って 1 列に表示します。 (この例では ls の出力先は cat ですから。)

もう少しわかりやすいように、less コマンドを組み合わせてみましょう。 less はページャーと呼ばれるコマンドで、 標準入力された文字列を 1 画面に入る分ずつ表示し、自由にスクロールアップ/ダウンできるようにして読みやすくするツールです。 1 画面に入りきらない長い文書を読むとき便利です。
$  ls -l  /usr/bin  |  less

画面の左下に反転した文字で [line 1] と表示されれば、less が起動している証拠です。 ls -l の出力が 1 画面分だけ表示されましたね? [↑]、[↓] キーや [Page Up]、[Page Down] キーで内容をスクロールできます。 終了するには [Q] キーを押します。

このようにパイプラインを使ってコマンドを組み合わせると、 単純なコマンドの組合せで驚くほど複雑な仕事を処理できます。その例は次のページ以降で説明します。
このページトップ目次へ
8. テキスト処理コマンド
Macintosh や Windows を使っている人が Linux ユーザーに尋ねる事で、 非常によく耳にするのは、
「で、Excel や 1-2-3 のような表計算ソフトはないの?」
という質問です。「ないのか?」 と聞かれれば、答は 「ある」 です。 Applixware の日本語版には Excel とよく似た表計算ソフトが入っていますし、 Noel という日本語表計算ソフトは無償で公開されています。
しかし、もっと重要なのは、そもそも Macintosh や Windows のデータ処理の手法や価値観を、Linux の世界に持ち込む必要は全くない!! という事です。 Linux の基本は、「単純なコマンドの組合せとユーザー自身のカスタマイズで、複雑なデータ処理を行う」 ことであって、「巨大な万能ソフトウェアで メモリを喰い散らす」ことではありません。

ここからは、最も基本的な Linux のテキスト処理コマンド、grep、sort、uniq、awk やシェル スクリプトを使って、どのようにデータ処理を行えるかをご紹介します。


grep コマンド
Linux でデータを扱うとき、基本になるデータ形式は 「テキスト」 です。 改行コード (0x0A) で区切られた複数の 「行」 の集まりです。 この 「行」 の中から、必要なデータを含む「行」 を捜し出すのが grep コマンドです。
例えば、/etc/passwd は Linux のユーザー情報のデータベースですが、 この中で自分に関するデータを検索してみましょう。
$  grep  kasahara  /etc/passwd     ←─ ユーザー名は適当に変えてください。

kasahara:x:10001:100:Hiroyuki Kasahara,,,:/home/kasahara:/bin/bash
私の場合、このようになっています。 左からユーザー名、パスワード、ユーザー ID、グループ ID、ユーザーの本名 (等)、 ホーム ディレクトリ、使用するシェル、の順番で : (コロン) で区切られたデータが並んでいます。
対象がこのようにちゃんとしたデータベース形式になっていない場合にも grep は有効です。 単なる複数のテキストファイルの中から、特定のキーワードを探し出す用途にも使えます。例えば、/etc/rc.d にある起動スクリプトの中の、 どのファイルで crond が起動されているか知りたいときは、
$  grep -n  crond  /etc/rc.d/rc.*

/etc/rc.d/rc.M:60:# Start crond (Dillon's crond):

/etc/rc.d/rc.M:63:/usr/sbin/crond -l10 >>/var/adm/cron 2>&1
のように実行すれば、/etc/rc.d/rc.M の 63 行目で起動されている事が わかります。ちなみに、この例では前の例と違う部分が 2 つあります。
grep で複数のファイルの中からキーワードを検索した場合、 検索結果の先頭にファイル名が挿入されます。 (これをオフにするには、-h オプションを指定します。)
grep に -n オプションを付けた場合、 ファイルの何行目で見つかったかが表示されます。
このページで説明できなかった以下のオプションも、頻繁に使用する機会があると思います。
-i : アルファベットの大文字と小文字の違いを無視します。
-v : キーワードの見つからなかった行を表示します。 つまり、通常と逆の動作になります。

sort コマンド
テキストの行を、指定した条件で並べ替えるのが sort コマンドです。 /etc/passwd ファイルで動作を試してみましょう。
$  sort  /etc/passwd

adm:x:3:4:adm:/var/adm:

bin:x:1:1:bin:/bin:

daemon:x:2:2:daemon:/sbin:

        :

        :

      (省略)

        :

        :

sync:x:5:0:sync:/sbin:/bin/sync

uucp:x:10:14:uucp:/var/spool/uucppublic:

wnn:*:10000:1:Wnn:/usr/lib/wnn:

アルファベット順に並べ替えられました。

注意 : /etc/passwd が書き換えられたわけではありません。並べ替えた結果をターミナルに表示しただけです。
では、今度はユーザー ID 順に並べてみましょう。 そのためには、いくつか考えなければいけない事があります。
ユーザー ID は 3 番目のフィールドなので、 3 番目のフィールドを使って並べ替えるように指定しなければなりません。 sort では、最初のフィールド、2 番目のフィールド、3 番目... を、+0+1+2 のように指定します。 最初のフィールドが +0 になることに注意してください。今は 3 番目のフィールドを使うので、+2 を指定します。

また、フィールドを区切る文字が : であることも指定しなければなりません。 (指定しない場合はスペースとタブによって区切られていると仮定されます。) これは -t オプションを使って指定します。 -t の後に使用する文字を記述します。

では実行してみましょう。
$  sort  -t : +2  /etc/passwd

root:x:0:0::/root:/bin/bash

wnn:*:10000:1:Wnn:/usr/lib/wnn:

kasahara:x:10001:100:Hiroyuki Kasahara,,,:/home/kasahara:/bin/bash

uucp:x:10:14:uucp:/var/spool/uucppublic:

operator:x:11:0:operator:/root:/bin/bash

        :

        :

      (省略)

        :

        :
何か、ちょっと変です。 ユーザー ID だけ並べてみると、このように並んでいます。
0

10000

10001

10

11
つまり、数字として認識しないで、単なる文字列として並べ替えているのです。これを正しく数字の順番に並べるには、-n オプションを指定します。

今度は正しく並びました。

この他にも、以下のオプションをよく使います。

  • -b : 行の先頭の空白を無視します。
  • -f : 大文字と小文字を区別しないでソートします。
  • -r : 並べ替える順番を逆にします。

uniq コマンド
2 行以上同じ内容の行が続いたとき、1 行にまとめてしまうのが uniq コマンドです。 例えば、
Do the Best at Yokohama Arena

Do the Best at Yokohama Arena

Taiyo On & Off

Peachberry Show

Peachberry Show

Peachberry Show
を uniq で処理すると、
Do the Best at Yokohama Arena

Taiyo On & Off

Peachberry Show
となります。 さらに -c オプションを付けると、このように重複した回数が行頭に表示されます。
      2 Do the Best at Yokohama Arena

      1 Taiyo On & Off 

      3 Peachberry Show
あらかじめソートされているデータしか処理できないので、 通常は sort コマンドと組み合わせて使用します。

さて、このコマンドが何の役に立つのでしょうか? 疑問に思う方もいるかもしれません。真面目な利用法を考えれば、例えばユーザー登録データベースで、 重複して登録しているユーザーを消去することができるでしょう。しかし、次のページではちょっと面白い利用法をご紹介します。


grep、sort、uniq を組み合わせた利用例
話が急に変わりますが、Netscape Communicator のメール機能で受信したメールは、ユーザーのホームディレクトリの nsmail ディレクトリに Inbox というファイル名で保存されます。 less などのコマンドで Inbox ファイルを見るとわかりますが、 これはメールヘッダと本文が長々と続く、単なるテキストファイルです。
ここでメールヘッダに注目すると、X-Mailer: というフィールドがあって、送信者が使っているメールクライアントの名称が記録されています。 ということは、このフィールドを抜き出してカウントすれば、各メールクライアントの普及状況がわかる (かな?) と思い、 処理する方法を考えてみました。
まず、Inbox から X-Mailer: フィールドだけを抽出します。 簡単に grep X-Mailer: でも良いのですが、 このキーワードは必ず行頭にあるはずなので、行頭を表す記号 ^ を付けて、 grep ^X-Mailer: で検索します。 (ちなみに、行末を表す記号は $ です。)
$  grep  ^X-Mailer:  ~/nsmail/Inbox

X-Mailer: Microsoft Outlook Express 4.72.3110.5

X-Mailer: Mozilla 4.05 [ja] (Win95; I)

X-Mailer: Microsoft Outlook Express 4.72.2106.4

X-Mailer: Microsoft Outlook Express 4.72.2106.4

X-Mailer: Microsoft Outlook Express 4.72.2106.4

X-Mailer: QUALCOMM Windows Eudora Pro Version 3.0.3-J (32)

        :

        :

      (省略)

        :

        :
うまく取り出せたようです。 次に sort ですが、これは uniq の前処理をしているだけなので、オプションを付けずに実行します。
$  grep  ^X-Mailer:  ~/nsmail/Inbox  |  sort

X-Mailer: ++Mail Version 2.21 (build 170)

X-Mailer: ++Mail Version 2.21 (build 170)

X-Mailer: ++Mail Version 2.21 (build 170)

X-Mailer: ++Mail Version 2.21 (build 170)

X-Mailer: AL-Mail32 Version 1.01

X-Mailer: AL-Mail32 Version 1.01

        :

        :

      (省略)

        :

        :
きれいに並びました。 そして、最後に uniq を実行します。 重複している回数を数えたいので、 -c オプションを付けます。
$  grep  ^X-Mailer:  ~/nsmail/Inbox  |  sort  |  uniq -c

      4 X-Mailer: ++Mail Version 2.21 (build 170)

      3 X-Mailer: AL-Mail32 Version 1.01

      4 X-Mailer: AL-Mail32 Version 1.10 beta7

      4 X-Mailer: AOL for Macintosh sub 32

      1 X-Mailer: Becky! ver 1.24.13

      1 X-Mailer: Denshin 8 Go V321.1b7

      1 X-Mailer: IBM King of Mail; V1.0.5.2; WIN32

      3 X-Mailer: Mew version 1.93 on Emacs 19.34 / Mule 2.3 (SUETSUMUHANA)

      5 X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0

     11 X-Mailer: Microsoft Outlook Express 4.71.1712.3

      7 X-Mailer: Microsoft Outlook Express 4.72.2106.4

     19 X-Mailer: Microsoft Outlook Express 4.72.3110.5

      3 X-Mailer: Microsoft Outlook Express 4.72.3155.0

      1 X-Mailer: Microsoft Outlook Express for Macintosh - 4.01 (295) 

      7 X-Mailer: Mozilla 3.01 [ja] (Macintosh; I; PPC)

      1 X-Mailer: Mozilla 3.01Gold [ja] (Macintosh; I; 68K)

      1 X-Mailer: Mozilla 3.01Gold [ja] (Win95; I)

      2 X-Mailer: Mozilla 4.03 [ja] (Win95; I)

      2 X-Mailer: Mozilla 4.04 [ja] (Win95; I)

     11 X-Mailer: Mozilla 4.05 [ja] (Win95; I)

      1 X-Mailer: Mozilla 4.05 [murikuri-ja_euc] (X11; I; Linux 2.0.34 i486)

      1 X-Mailer: Mozilla 4.05 [murikuri-ja_euc] (X11; I; Linux 2.0.34 i586)

      1 X-Mailer: Mozilla 4.05 [muriyari-ja_euc] (X11; I; Linux 2.0.34 i586)

      1 X-Mailer: Mozilla 4.05 [muriyari-ja_euc] (X11; I; Linux 2.0.34 i686)

      1 X-Mailer: Mozilla 4.07 [en] (Win98; I)

      2 X-Mailer: Mozilla 4.07 [murikuri-ja_euc] (X11; I; Linux 2.0.35 i586)

      6 X-Mailer: Mozilla 4.5 [ja] (Win95; I)

      2 X-Mailer: QUALCOMM Windows Eudora Pro Version 3.0.2-J (32)

      4 X-Mailer: QUALCOMM Windows Eudora Pro Version 3.0.3-J (32)

      5 X-Mailer: Windows Eudora Pro Version 3.0-J (32)

      2 X-Mailer: ccMail Link to SMTP R6.00.02

これは、最近 1 週間の間に私に届いたメールで、実際に試してみた例です。 Outlook Express が多いなぁ、というのが率直な感想です。 AL-Mail や Becky! は思ったより少なく、Eudora Pro は意外に (というと失礼かもしれませんが) 多いです。 もちろん統計的な有効性は全くありませんが (^^;

どうですか? 簡単でしょ? grep、sort、uniq の 3 コマンドだけでも、けっこう面白い使い方ができるものです。いろいろ使い方を考えてみてください。

awk コマンド
grep コマンドを拡張して、プログラミング言語的な機能まで持たせたのが awk です。 awk の機能はあまりにも多いので全ては説明できませんから、 よく使うフォーマット機能と計算機能を簡単にご紹介します。 (awk については詳しい解説書も市販されていますので、詳細はそちらをどうぞ。)

まじめに説明すると大変なので、簡単な例を使うことにします。

grep の説明で /etc/passwd を使いましたが、 このファイルは人間にはとても見にくいものです。そこで、awk の機能でユーザー kasahara のユーザー名とホーム ディレクトリだけを取り出して、見やすく出力したのが次の例です。  
$  awk  -F :  '/kasahara/{print $1 " = " $6}'  /etc/passwd

kasahara = /home/kasahara
このコマンドラインを順番に見ていきます。

-F : の部分は、 対象となるファイルのフィールドが : で区切られているという事を示しています。
'/kasahara/{print $1 $6}' が処理の内容の指定で、
最後の /etc/passwd が対象ファイルの指定です。

処理の内容は、
'/検索する文字列/{命令}'
という構成になっています。 つまり、"検索する文字列" を含む行では、"命令" を実行されます。 さらに複雑な処理をしたい場合は、
'/検索する文字列 1/{命令 1}  /検索する文字列 2/{命令 2}  {命令 3}'

のように、複数の組合せを指定できます。 こうすると、"検索する文字列 1" を含む行では "命令 1" が実行され、 "検索する文字列 2" を含む行では "命令 2" が実行されます。 検索する文字列を伴わない "命令 3" は、すべての行に対して実行されます。

最初の例に戻ると、命令は {print $1 " = " $6} となっています。 print は、引数として与えられた文字列を出力する命令です。 引数が与えられない場合は行全体を出力します。 (ということは、つまり awk '/kasahara/{print}' /etc/passwd は、grep kasahara /etc/passwd と 同じ処理になります。)

引数として与えられている $1 と $6 は、それぞれ 1 番目と 6 番目のフィールドを表します。 /etc/passwd の例では、ユーザー名とホームディレクトリです。

$1 と $6 の間にある " = " は、ただの文字列です。 awk では、スペースで区切られた文字列は連結されるので、$1 " = " $6 は一つの 文字列として print で出力されます。

ここで、次の例のように検索する文字列 /kasahara/ を削除してしまえば、すべての行がフォーマットされて出力されます。
$  awk  -F :  '{print $1 " = " $6}'  /etc/passwd

halt = /sbin

operator = /root

root = /root

shutdown = /sbin

sync = /sbin

bin = /bin

ftp = /home/ftp

daemon = /sbin

adm = /var/adm

lp = /var/spool/lpd

mail = /var/spool/mail

postmaster = /var/spool/mail

news = /usr/lib/news

uucp = /var/spool/uucppublic

man = /usr/man

games = /usr/games

guest = /dev/null

nobody = /dev/null

wnn = /usr/lib/wnn

kasahara = /home/kasahara

C 言語をご存知の方なら、printf 命令を使って {printf "フォーマット文字列", 引数 1, 引数 2, ...} というより細かいフォーマット指定も可能です。

次の例では、前に使った Netscape の Inbox をもう一度使い、 X-Mailer: フィールドに Mozilla という文字列が入っている行と、 Outlook Express という文字列が入っている行を数え、結果を出力します。
$  awk  'BEGIN{NS=0; OE=0} /^X-Mailer:/&&/Mozilla/{NS++} /^X-Mailer:/&&/Outlook Express/

{OE++} END{print "Mozilla = " NS; print "Outlook Express = " OE}'  ~/nsmail/Inbox

   (↑一行に入力します。)

Mozilla = 37

Outlook Express = 41
なかなかいい勝負... という結果は置いておき、 ここまで長くなると一目で理解できる人は少ないでしょうから、処理内容の部分を少しわかりやすくフォーマットしなおし、 解説を加えました。
BEGIN {NS=0; OE=0} 

                          BEGIN{} の処理は、awk の開始時に 1 回だけ実行されます。

                          変数の初期化などに使います。{ } の中に 2 つ以上の命令を

                          記述するときは、; (セミコロン) で区切ります。



/^X-Mailer:/ && /Mozilla/ {NS++} 

                          ^X-Mailer: を含み、かつ Mozilla も含んでいる行があった

                          場合、変数 NS を +1 します。

                          && は AND の意味です。 OR なら || です。

                          ^ は行頭を表す記号です。 grep と同じです。



/^X-Mailer:/ && /Outlook Express/ {OE++} 

                          Outlook Express の時は、変数 OE を +1 します。



END {print "Mozilla = " NS; print "Outlook Express = " OE} 

                          END{} の処理は、全ての行を処理した後で実行されます。

                          この例では、単に NS と OE の値を 2 行に分けて出力します。
さて、それならばということで、この 4 行をあらかじめファイルに保存しておけば、毎回この長いコマンドを入力しなくて済みます。
BEGIN {NS=0; OE=0}

/^X-Mailer:/ && /Mozilla/ {NS++}

/^X-Mailer:/ && /Outlook Express/ {OE++}

END {print "Mozilla = " NS; print "Outlook Express = " OE}
これを ns_vs_oe というファイル名で保存した場合、 awk の -f オプションでそのファイル名を指定して、
$  awk -f  ns_vs_oe  ~/nsmail/Inbox

Mozilla = 37

Outlook Express = 41

このように簡単なコマンドで上の処理を実行できます。 このコマンドラインを ~/.profile に書き込んでおけば、 ログインするたびに Netscape と Outlook Express のどちらが優勢かの 最新情報が表示されて面白いです。 (面白いかなぁ...?)

このページトップ目次へ
9. シェル スクリプト
Linux の操作をより便利にする上で、シェル スクリプトの作成は欠かせません。タイプするのが面倒な長いコマンドラインも、 シェル スクリプトにしてしまえば簡単に実行できます。しかも、シェル スクリプトを作成するのは 「とても簡単」 です。

シェル スクリプトを動作させるには次の条件が必要です。

  • スクリプトとして実行するファイルの先頭が #!/bin/sh で始まっている。
  • ユーザーの環境変数 PATH で指定されたディレクトリにファイルが保存されている。
  • ファイルの実行可能属性 (x 属性) が有効になっている。
実際にシェル スクリプトを作成してみましょう。 例として、grep、sort、uniq の説明で使った、 メールクライアント数を調べる処理をシェル スクリプトにしてみます。
まずテキストエディタで新規のファイルを作成し、先頭に次の文字列を入力します。
#!/bin/sh
これは単なる約束事で、このスクリプトを /bin/sh で実行するように指示しています。 2 行目以降は、自由に Linux のコマンドを書き込めます。 (# で始まる行はコメント行となり無視されます。)
次のコマンド列を 2 行目に入力してください。
grep  ^X-Mailer:  ~/nsmail/Inbox  |  sort  |  uniq -c
これで終わりです。たった 2 行のスクリプトですが、 これだけの処理を一つのコマンドで実行できれば大変便利です。
#!/bin/sh

grep  ^X-Mailer:  ~/nsmail/Inbox  |  sort  |  uniq -c
このファイルを保存する場所ですが、いつでも実行できるようにするには、環境変数 PATH で指定されたディレクトリに保存する必要があります。 /bin や /usr/bin には書き込み権がないでしょうから、 通常自分専用のスクリプトは ~/bin (ホームディレクトリの下の bin ディレクトリ) に保存します。 『手とり足とり Linux』 のインストール編にしたがってインストールした場合、 このディレクトリは PATH に含まれています。

以下の例では、~/bin/count_mail というファイル名で保存することにします。

あとは、このファイルを実行可能にするだけです。 chmod コマンドを次のように実行します。
$  chmod  ugo+x  ~/bin/count_mail
それでは実行してみましょう。
$  count_mail

      4 X-Mailer: ++Mail Version 2.21 (build 170)

      3 X-Mailer: AL-Mail32 Version 1.01

      4 X-Mailer: AL-Mail32 Version 1.10 beta7

      4 X-Mailer: AOL for Macintosh sub 32

        :

        :

      (省略)

        :

        :
前と同じ結果になりました。
ただ、これではあまりにも汎用性のないスクリプトなので、 他の用途にも使えるように若干修正してみましょう。もう一度 count_mail を開いて、次のように変更してください。 (赤い文字が修正部分です。)

#!/bin/sh
grep  ^$1:  ~/nsmail/Inbox  |  sort  |  uniq -c

こうすると、count_mail の最初の引数が $1 のところに挿入されます。 (2 番目の引数を挿入するなら $2、3 番目は $3、といった具合に指定します。引数全体を挿入するなら、$@ を使います。)
つまり、
$  count_mail  X-Mailer
と入力すれば今まで通りに動作するわけですが、
$  count_mail  From

と変えれば、今度は差出人別に何通の E-Mail を送ってきたかを集計できます。 (プライバシーの保護のため、出力サンプルは割愛します ^^;)

この場合、もう一度 sort -n をかけて件数順に並べ替えた方が見やすいようなので、次のようにした方が良いかもしれません。
$  count_mail  From  |  sort -n

組み合わせは自由!! どうにでもなるのです。

最後に
ここまでの説明でフィーリングをつかんでいただけたでしょうか? 小さいプログラムをうまく組み合わせて、あとは要所要所で適切なスクリプトを作っていけば、だいたいの事はできるものです。
このページトップ目次へ

有限会社ケーエイチシー 〒806-0013 北九州市八幡西区清納1-2-30 
TEL 093-681-4618  FAX 093-681-4619 福岡県公安委員会許可第34618号古物商 
E-Mai:info@shop-khc.jp   URL:http://www.shop-khc.jp