next up previous contents
Next: 6 ジョブ制御 Up: UNIX 基礎演習 B 組 Previous: 4 標準入出力とリダイレクト

Subsections


5 パイプとフィルタ

5.1 復習 -- 標準入出力のリダイレクト

ディレクトリ /etc に存在する全ファイルの詳細情報を調べましょう。

ls -la /etc
/etc にはファイルがたくさんあるので,画面にすべてを表示しきれませんね。 どうしたらいいでしょう。

一つの解決策として,

  1. ls -la の出力を一旦ファイルに保存して
  2. そのファイルの内容をエディタ等で見る
ことが考えられます。このための操作を実際に行いながら, 標準入出力の切り替え(リダイレクト)について,復習しておきましょう。

  1. ls コマンドの出力は,通常,標準出力を通じて画面に表示されますが, ls の出力をファイルに保存するには標準出力をファイルに切り換えれば いいですから,リダイレクト (>) を使って
    ls -la /etc > etcfiles
    を実行します。シェルの入力支援機能を積極的に利用して,タイプの手 間をできるだけ省いてください15
    \includegraphics[clip]{4_stdout}

    1. etcfiles の中身を見るために Emacs を起動してもいいのですが, ファイルの中を見るだけであれば,more を使うのが便利です 16 17 。まず,etcfiles が存在することを確認してから
      more etcfiles
      を実行してみてください。more の操作方法は,man コマンドに よるマニュアルページの閲覧方法と同じです 。だって,man は内部的に more を呼び出して,マニュア ルを表示しているのですから。

    2. 次に
      more < etcfiles
      を実行してください。< の有無に拘らず実行結果は同じ ですが,more の内部的な動作は異なります。more は引数にファ イル名が与えられれば,そのファイルを直接読み込みます。一方, 引数を与えずに < に続いてファイル名を指定すると,標 準入力からファイルを読み込みます(標準入力のリダイレクト)。
      \includegraphics[clip]{4_stdin}
      なお,more は処理結果を標準出力に出力しますが,その先につ ながっているのは,これまでと同様に通常は画面です。

  2. 以上で目的は達成されましたので,etcfiles は不要になりました。削除 しましょう。
    rm etcfiles

5.2 パイプ

ls の出力を見たいだけなのに,それを一時的にファイルに保存してから more で見て,見終わったら rm で削除するというのでは,あまりに不便ですね。パイ プを使うと,ファイルを介さずに,前節と同様のことを一度の操作で行うことが できます。

5.2.1 コマンドの連結 -- パイプ

あるコマンドの標準出力を,ファイルではなく,別のコマンドの標 準入力に直接連結することが可能です。その操作をパイプと呼びます。 パイプは,コマンド行において,一連のコマンドを「縦棒 (|)」で区切っ て記述することによって行います。パイプによって連結された一連のコマンドを パイプライン (pipeline) と言います。

なお,csh や tcsh において,コマンドの標準出力と標準エラー出力の両方を次 のコマンドの標準入力に連結するには | の代わりに |& を使い ます。


では,/etc に存在する全ファイルの詳細情報を,パイプを使って一度に表示し て閲覧してみましょう。

ls -la /etc | more
この状況を示したものが次の図です。図では ls の引数 (-la /etc) の記述は 省略しています。
\includegraphics[clip]{4_pipe}
動作の概要は以下のとおりです。
  1. ls が実行結果を標準出力に出力します。

    ls の標準出力をパイプによって more の標準入力に連結しているので, ls の実行結果は画面には出力されません。

  2. more が ls の実行結果を標準入力から受け取り,標準出力を通じて画面 に表示します。
    1. more は,一画面分以上の入力を受け取ると対話的な動作をしま すので,一画面分の表示を終えたところで表示を止め,ユーザー からの命令を待っている状態になります。
    2. ユーザーがスペースキー等を押して全ページを表示させ終えるか, q 等を押すことで more を終了させると, パイプライン全体が終了し,プロンプト が帰ってきます。

5.2.2 コマンドの多段連結

三つ以上のコマンドをパイプすることもできます。次の図に示すように, command1 が標準出力 (stdout) に結果を出力するコマンドであり,command2command3 がともに標準入力 (stdin) から入力を読み取っ て結果を標準出力 (stdout) に出力するコマンドであるとすれば,
command1 | command2 | command3
のような多段のパイプが可能です。この場合,command1 の出力が command2 の標準出力を通って処理され,さらに command3 で処理されま す。
\includegraphics[clip]{4_multi_pipe}
なお,これまでと同様に,各コマンドに引数を与えてパイプすることも可能です。

5.3 フィルタ

先の command2command3 のように,標準入力と標準出力を使っ た入出力が可能なコマンドをフィルタ (filter) といいます。フィルタは パイプラインの中で利用できるコマンドです。

これまでに紹介したコマンドでは

cat, grep, head, sort, tail, tr, uniq, wc
はフィルタです。各コマンドの動作を忘れていたら,マニュアルページ等で 確認してください。

5.4 問題

カレントディレクトリを,第 4.4 節の問題で作成したディレ クトリ (/unix/part4) に変更してから以下の問題を解いてください。

  1. カレントディレクトリに存在するファイル(. で始まるものは除く)の 個数を求めましょう。

    1. まず,ls の出力を一度ファイルに保存してから,その中身を確 認してください18。そのファイルを wc コマン ドで処理して,期待する結果が得られたか確認してください。

      うまくいったら,ここで作成したファイルは削除しましょう。

    2. ls の出力をファイルに保存せずに,パイプを使って上記と同様 のことをしてください。

  2. 4.4 節の問題 3. で作成したファイル campus の 中身を,sort コマンドで辞書順に並べ替えて画面に表示しましょう。た だし,各単語は一回のみ表示することとします。

  3. 前の問題での表示を全て大文字にしましょう。

  4. ホームディレクトリに存在するファイルの中から,昨年の 12 月に作成 または更新したファイルの一覧を表示しましょう。ここではファイル名 に Dec を含むファイルが存在しないことを前提として,ls と grep コマンドを使うことにします。

    grep は,引数で与えた文字列パターンを含む行のみを抽出して,標準出 力に出力するコマンドです。

    grep pattern file...
    の書式で実行すると,grep はfile... から patten を含む 行のみを抽出しますが,file... を省略すると,標準入力から入 力を読み込みますので,フィルタとして利用できます。

    この問題をリダイレクトを使って解くには,例えば

    ls -l > temp
    grep Dec temp または grep Dec < temp
    rm temp
    を実行します。

    さて,パイプを使って上記に相当する操作を行ってください。

  5. ホームディレクトリに存在する,昨年の 12 月に作成または更新したファ イルの個数を求めましょう。

  6. file... の内容を行番号付きで出力するには cat -n  file... または cat -n < file... とします。

    4.4 節で作成したファイル campus と CAMPUS を 同時に cat の引数に与えて実行してみてから,それを行番号付きの表示 にしましょう。さらにその表示を最初の 5 行分のみにしましょう。head コマンドも使います。

  7. who コマンドを使うと,同じ計算機を使っているユーザーを調べることが できます。

    同じ計算機を使っているユーザーを,辞書順に並べて表示しましょう。

    さらに,その結果に行番号を付けて出力しましょう。引数にファイル名 を指定せずに cat コマンドを使うと,cat は標準入力から入力を読み込 みます。

  8. パイプを使って,who の出力の中から自分の情報のみを出力しましょう。 さらに,リダイレクトを使って,その出力を適当なファイル名を持つファ イルに保存しましょう。

    利用者が自分一人のときだけ上手くいってもだめですよ。 who am i もなしです。


next up previous contents
Next: 6 ジョブ制御 Up: UNIX 基礎演習 B 組 Previous: 4 標準入出力とリダイレクト
Hideaki Konno
平成17年1月27日