# 17.5. パイプとリダイレクション
**Source**: https://hwb.ecc.u-tokyo.ac.jp/hwb2023/applications/shell/pipe_and_redirection/
**Parent**: https://hwb.ecc.u-tokyo.ac.jp/hwb2023/literacy/email/
ターミナル上で動かすコマンドは、通常キーボードから入力を受けて画面に出力を返します。しかしパイプとリダイレクションの機能を使うことで、この入出力先をファイルに切り替えたり、コマンドの出力を別のコマンドの入力に渡すことができます。
## パイプ [#](#pipe)
**パイプ**は、あるコマンドの出力を別のコマンドの入力とする機能です。縦棒 `|` でコマンドをつないでやることにより、前のコマンドの出力が後ろのコマンドの入力となり、複数のコマンドを連携させることができます。
例えばホームディレクトリで `ls -la` と打つと、沢山のファイルがあるばあいは画面が一瞬で流れていってしまうでしょう。このように出力が一画面に収まらないときは、`less` と組み合わせるとよいです。`less` はテキストファイルの内容を 1 画面分ずつ表示することができるコマンドです。具体的には
ls | less
のようにします。`ls` の出力をパイプを使って `less` に送ることにより、出力を少しずつ見ることができます。普通は `less` というコマンドはパラメータとしてファイル名を指定して
less filename
のように使いますが、パイプの後のコマンドとして使うときは、パラメータを書きません。ファイルから入力を読み込むのではなく、パイプの前のコマンドの出力が入力となるからです。他のコマンドをパイプのあとに使う場合でも同様です。
もう一つ便利な例を紹介しましょう。`ls` の出力から、`.txt` を含んだ行だけ取り出したいときは、`ls` と `grep` を組み合わせればできます。次の例のようにすると `ls` の出力が `grep .txt` に渡され、`grep` が `.txt` を含む行だけを選別して表示してくれます。
ls | grep .txt
つまり、カレントディレクトリにあるテキストファイルだけの一覧が作れたわけです。
パイプは複数繋げることもできます。たとえば `wc` コマンドに `-l` オプションを付けて呼び出すと、与えられたテキストファイルの行数をカウントしてくれます。そこで、次のように入力してみましょう。
ls | grep .txt | wc -l
上で説明した通り、`ls | grep.txt` の部分によって、カレントディレクトリのテキストファイル一覧が表示されます。これが再びパイプによって `wc -l` に渡されると、`ls | grep.txt` の出力の行数がカウントされます。すなわち、カレントディレクトリにあるテキストファイルの個数が数えられます。
## リダイレクション [#](#redirection)
プログラムはなんらかの文字列を出力することがあります。例えば
ls
とすれば、今のディレクトリにあるファイル一覧という文字列が出力されます。また上のパイプの説明で例として挙げたように、more コマンドは別のコマンドの出力を入力として受け取ります。この入力先や出力先をファイルに変更することを**リダイレクション**、あるいは**リダイレクト**と呼びます。
例えば `ls` の出力を `files.txt` というファイルに保存したい場合、以下のように入力します。
ls > files.txt
不等号の大なり `>` のあとにファイル名を書くことによって、標準出力がそのファイル名を持ったファイルとなります。単純にターミナルの画面で ls を打った結果と files.txt をテキストエディタで開いた結果を見比べて、リダイレクトできていることを確かめてください。
別の例として、ターミナル上で簡単にテキストファイルを作る方法を紹介します。たとえば `hello` という 5 文字の内容をもつファイル `aisatu.txt` を簡単に作ってみましょう。これは `echo` というコマンドで実現できます。`echo` は、パラメータに与えた文字列を標準出力に出力するコマンドです。たとえば `echo hello` と入力すると、画面に `hello` が出力されます。
echo hello
```
hello
```
そこで `echo` の結果を `aisatu.txt` にリダイレクトすれば、`hello` と書かれたテキストファイルができます。
echo hello > aisatu.txt
もし上のコマンドを打つ前に `aisatu.txt` が存在していたら、上のコマンドの結果によって `aisatu.txt` が上書きされます (設定によってはエラーになります)。一方、大なり記号を 2 つ重ねた `>>` でリダイレクトをすると、出力結果が既にあるファイルの末尾に追記されます。たとえば
echo konnichiha >> aisatu.txt
のように `>>` を使うと、`aisatu.txt` の内容は、既にあった内容の最後に今回の行が加わったものになります。実際に `cat` コマンドで確認すると
cat aisatu.txt
```
hello
konnichiha
```
と表示されるはずです。最後に、文字コードを変換する `nkf` というプログラムを使ってみましょう。(文字コードについては[14. 情報の表現と符号化・暗号化](https://hwb.ecc.u-tokyo.ac.jp/hwb2023/information/coding)
を参照してください。) `nkf` は `-w8` オプションをつけて
nkf -w8 filename
のように呼ぶと、`filename` という名前のファイルを UTF-8 に変換し、その結果を画面に表示します。いま、Shift-JIS コードで書かれた `memo.txt` というファイルがあるディレクトリで
nkf -w8 memo.txt
と入力したとしましょう。すると `memo.txt` の中身を UTF-8 に変換した結果が、画面にどんどん書き出されていきます。そこでリダイレクションを利用して
nkf -w8 memo.txt > memo\_utf8.txt
とすれば、文字コードを UTF-8 に直した結果が `memo_utf8.txt` に格納されます。このテクニックは、古い環境で作られたテキストファイルを文字化けしないようにする目的に使えます。