|
UNIX で最も基本的なファイル形式は「テキストファイル」です。UNIX は設計段階からテキストファイルをなるべく用いるという思想で設計されており、/etc の設定ファイル、/usr/share のドキュメント類、/var/log のログなど、UNIX システムの情報の多くはテキストファイルで与えられます。さらに、スクリプト・メール・プログラミング・TeX …と、UNIX におけるテキストの重要性は強調してもし過ぎることはありません。
| |
|
|
このように重要なテキストファイルですから、UNIX ではテキストを取り扱うツールが非常に充実しています。 これらのツールひとつひとつは単純な機能しか持っていませんが、引数にファイル名を指定しなければ「標準入力を読んで処理結果を標準出力に書き出す」、いわゆる「フィルタ」としても働くため、| (パイプ) でツールを繋げば複雑なテキスト処理もできるようになっています。このパイプを使ったテキスト処理というのは、最も「UNIX 的」な作業ですので是非会得したいところです。それでは、基本的なテキスト処理ツールを順に説明していきましょう。
| 4.3.2 テキストファイルを見る (lv, less/jless)
|
|
| |

ツールとは、単純な機能で応用が利くという文字通りの「工具」のようなソフトウェアです。
|
|
lv は多国語化されたテキストビューアです。多国語化と銘打つだけあって英語や日本語だけでなく、中国語や韓国語などのテキストも正しく扱えます。
[↑][↓]だけでもテキストを読めますが、以下のショートカットキーをいくつか覚えればさらに快適になります。
|
|
次/前のページ (PageDown,PageUp で代用可)
|
|
|
|
|
ファイルの末尾/先頭へ移動 (指定行への移動もできる)
|
|
|
|
|
続けて入力した文字列をテキストの末尾/先頭へ向かって検索
|
|
|
|
|
直前に検索した文字列をテキストの末尾/先頭へ向かって再検索
|
|
|
|
|
ファイル名・行番号・文字コードなどファイルの情報を表示
|
|
|
>,< コマンドで指定した行へ移動するには、コマンドの前に行数の数値を入れます。例えば、300> とすると 300 行目に移動できます。
| |

その場合は gnome-terminal のような多国語に対応した端末を使って下さい。
|
|
/,? コマンドで検索するときは、コマンドに続けて検索したい文字列を入力し最後に Enter を押します。検索する文字列には正規表現も使えます。less とその日本語対応版 jless は、歴史と認知度では lv を上回りますが、国際化などの面で lv の方が優れているため、ARMA では lv を標準テキストビューアに採用しています。しかし、元々 lv は less の操作感を参考に作られたツールなので、lv と less の操作はほぼ同じになっています。
| 4.3.3 先頭・末尾を切り出す (head,tail)
|
|
head, tail はテキストファイルの先頭・末尾を指定した行数だけ表示します。これらを使うと先頭・末尾部分を確認するためだけに、いちいち lv を立ち上げないで済みます。
|
$ head [-c <バイト数> | -n <行数>] [<ファイル>]
| $ tail [-c <バイト数> | -n <行数>] [-f] [<ファイル>]
|
|
|
オプションを指定しない場合はテキストファイルの先頭・末尾の 10 行を表示しますが、以下のオプションによって表示する範囲を変えられます。
|
|
表示する部分をバイト単位で指定 (数値に k,m を付けると KB,MB 単位)
|
|
|
tail -f では一定の間隔でファイルの末尾を監視して、末尾に追加された部分を随時表示していくため、内容が刻々と追加されていくログなどを監視するときなどに便利です。
|
# tail -f /var/log/messages
|
|
|
| 4.3.4 文字列を検索する (grep, zgrep, bzgrep, lgrep)
|
|
| |

正規表現についてはここでは詳しく説明できませんが man 7 regex に詳しく書かれていますので、そちらを参照して下さい。正規表現はいわばワイルドカード(*)の超高機能版です。
|
|
grep はテキストから正規表現を検索して、それが見つかった行を表示するツールです。
|
$ grep [<オプション>] <正規表現> [<ファイル(複数可)>]
|
|
|
オプションを指定しない場合は単純に正規表現を検索し、見つかった (ヒットした) 行だけを表示しますが、以下のようなオプションによって動作を変えられます。
zgrep, bzgrep は内部的に gzip, bzip2 と grep を呼び出すスクリプトで、圧縮された *.gz や *.bz2 形式のテキストファイルを検索できるようになっています。
また、lgrep は lv の検索機能を呼び出すもので、grep 互換のオプションは -v, -n 程度しかありませんが、文字コードに関係なく日本語の検索を正しく行えます。
| 4.3.5 辞書順・数値順に行を並べ替える (sort)
|
|
sort はテキストを行単位で文字コード順に並べて表示するツールです。米語の文字コード (ASCII) は A 〜 Z, a 〜 z の順に並んでいるので sort を使うと、ちょうど辞書 (ABC) 順に整列できます。ただし、日本語の場合は sort すると漢字コード順になりますが、漢字コードは五十音順ではありません。
|
$ sort [<オプション>] [<ファイル(複数可)>]
|
|
|
オプションを指定しない場合は行単位で文字コード順、もう少しラフに言うと「ABC 順」に並べますが、以下のようなオプションによって動作を変えられます。
|
|
数値順に整列 (-g は浮動小数点なども扱えるが遅い)
|
|
|
|
|
タブや空白区切りの m 〜 n 番目を比較対象にする
|
|
|
-n の「数値順ソート」は、0 〜 9 を単純に文字コードで比較するのではなく、特別にひとかたまりの数値として比較します。例を挙げて見てみましょう。
|
$ cat n_sort
| 100
| 20
|
| $ sort n_sort
| 100
| 20
|
| $ sort -n n_sort
| 20
| 100
|
|
|
100 と 20 を普通にソートすると、文字コードでは 1 の方が 2 より前なので、100 → 20 の順になります。しかし、数値順ソートでは 100 と 20 を数値として認識し、小さい順に並べるので 20 → 100 になります。さらに、-g では -f で数値と認識できない 1.23e45 のような浮動小数点や +6.78 のようなプラス符号も扱えますが、動作は -n よりもだいぶ遅くなってしまいます。
-k では、タブや空白文字で区切られた区切りを「フィールド」として、フィールド単位でのソートを行うオプションです。まずは、ひとつ実例を見てみましょう。
|
$ cat k_sort
| 2 100
| 1 3
| 3 20
|
| $ cat -k1,1 k_sort
| 1 3
| 2 100
| 3 20
|
| $ cat -k2,2 k_sort
| 2 100
| 3 20
| 1 3
|
| $ cat -k2n,2 k_sort
| 1 3
| 3 20
| 2 100
|
|
|
この例では、空白で区切られた各数値がフィールドになります。-k1,1 では各行の第 1 フィールドだけを見て文字コード順にソートしています。これに対し、-k2,2 では第 2 フィールドがソート対象になっています。さらに、-k2n,2 とフィールドに n を付けると数値順ソートをします。
また、フィールド内で、ソート対象を文字単位で指定することもできます。例えば、第 1 番目のフィールドの第 2 文字から第 3 文字までをソート対象にするなら -k1.2,1.3 と指定します。
uniq は辞書順にソートされたテキストから連続する同一内容の行をまとめて、2 回あっても 3 回あっても 1 回だけ表示するツールです。従って、パイプで uniq を使うときは、前に必ず sort を通しておかなければなりません。
|
$ uniq [<オプション>] [<ファイル>]
|
|
|
| |

grep という名前は sed で「正規表現を検索して、それが見つかった行を表示する」という意味のコマンドの g/RE/p (RE = Regular Expression = 正規表現) に由来します。
|
|
以下のオプションによって、動作を変えられます。
-f,-s を両方指定したときは、まず n フィールド飛ばし、さらに次のフィールドの先頭から m 文字を飛ばして uniq します。
| 4.3.7 バイト数・単語数・行数を数える (wc)
|
|
wc はテキストファイルのバイト数・単語数・行数を表示するツールです。
| |

フィールドの意味は sort の項で紹介したものと同じです。
|
|
ただし、単語数は「分かち書き」されたものを数えますので、日本語のように単語を分かち書きをしない言語では正しく単語を数えられません。また、日本語ではバイト数は文字数と一致しません。いわゆる「半角文字」が 1 文字 1 バイトで「全角文字」は 1 文字 2 バイトであるのはもちろん、UTF や ISO-2022-JP ではエスケープシーケンスもあるので単純にバイト数から文字数は計算できません。よって、日本語テキストファイルを wc にかけるとき、実質的な意味がある数値は行数だけと言えます。
オプションを指定しない場合はバイト数・単語数・行数を全て表示しますが、以下のようなオプションによって動作を変えられます。
-L は他と少し旗色の違うオプションですが、メールなどで 1 行の長さを制限しなければならない場合などの確認に便利です。
diff は行単位で 2 つのファイルを比較し、差がある行を出力するツールです。
|
$ diff [<オプション>] <ファイル1> <ファイル2>
|
|
|
オプションを指定しない場合は単純に 2 つのファイルの差分を表示しますが、以下のようなオプションによって動作を変えられます。
-b では、例えば ho ge (スペース×1) と ho ge (スペース×2) のようなスペースの数だけが違う行を同じものとみなします。-w では、さらに hoge (スペース×0) のようなスペースを含まないものも同一視します。
-N は、主に -r でディレクトリの中身を丸ごと比較する場合に合わせて使うオプションで、片側にしかないファイルも、もう片方では空のファイルがあるかのように装います。実際の例を見て、説明に代えましょう。ここでは、dir1/x-file はあるが、dir2/x-file はないものとします。
|
$ diff -r dir1 dir2
| Only in dir1/: x-file
|
| $ diff -rN dir1 dir2
| diff -rN dir1/x-file dir2/x-file
| 1c1
| < This is dir1/x-file.
|
|
|
-N を指定していると dir2/x-file という空のファイルがあると見なして diff の結果が示されています。
さて、以下のような 2 つのファイルを実際に diff してみて、context , unified などの各出力形式について説明します。
|
$ cat hoge1
| 1行目
| 2行目 (hoge1 の 2 行目)
| 3行目
|
| $ cat hoge2
| 1行目
| 2行目 (hoge2 の 2 行目)
| 3行目
| 4行目
|
|
|
出力形式を指定しなかった場合は、古典的な出力形式になります。
|
$ diff hoge1 hoge2
| 2c2
| < 2行目 (hoge1 の 2 行目)
| ---
| > 2行目 (hoge2 の 2 行目)
| 3a4
| > 4行目
|
|
|
2c2 とは、差分が hoge1 の 2 行目と hoge2 の 2 行目であることを意味します。そして、< マーカで始まる行に hoge1 の、> マーカで始まる行に hoge2 の内容がそれぞれ出力されています。
context 形式は、差分行の前後数行を「文脈行」として出力します。文脈行は、diff の出力が人間にとって見やすくなるだけでなく、patch の動作する助けにもなります。
|
$ diff -c hoge1 hoge2
| *** hoge1 Mon Jun 25 17:00:08 2001
| --- hoge2 Mon Jun 25 16:59:59 2001
| ***************
| *** 1,3 ****
| 1行目
| ! 2行目 (hoge1 の 2 行目)
| 3行目
| --- 1,4 ----
| 1行目
| ! 2行目 (hoge2 の 2 行目)
| 3行目
| + 4行目
|
|
|
| |

英語では ``This is a pen.'' のように単語の間を空けて書きます。wc はこの間の空白文字を見て単語の数を数えています。
|
|
*** から始まる行は hoge1 に、--- から始まる行は hoge2 に関するものです。例えば *** 1,3 **** は続く出力が hoge1 の 1 〜 3 行目であることを表しています。また、! マーカは両ファイルで内容が異なる行を、+ マーカは file2 にしかない行を表しています。- と + のマーカは diff を「hoge1 から hoge2 への変化」と考えれば、「消滅した(-)行」「出現した(+)行」と直観的に覚えられると思います。
さて、unified 形式も文脈行を表示するのですが、context 形式のように 2 つのファイルの内容を交互に書かずにまとめて出力します。
|
$ diff -u hoge1 hoge2
| --- hoge1 Mon Jun 25 17:00:08 2001
| +++ hoge2 Mon Jun 25 16:59:59 2001
| @@ -1,3 +1,4 @@
| 1行目
| -2行目 (hoge1 の 2 行目)
| +2行目 (hoge2 の 2 行目)
| 3行目
| +4行目
|
|
|
@@ -1,3 +1,4 @@ は file1 の 1 〜 3 行目と file2 の 1 〜 4 行目の差分であることを意味します。- と + のマーカの意味は context 形式と同様です。
日本語には ISO-2022-JP, EUC-JP, ShiftJIS の 3 種類の文字コードがあります。これらのコードは「メール用」「UNIX 標準」「Windows 標準」とそれぞれにそれなりの役割があるので、普通に ARMA を使うだけでも 3 種類の文字コードそれぞれで書かれた日本語テキストに接することになるでしょう。これらを相互に変換するのが文字コード変換ツールの役割です。
日本語コードの変換も lv が便利です。
|
$ lv [-k] [-I<変換前文字コード>] -O<変換後文字コード> <ファイル>
|
|
|
-I に続いて変換前の、-O に続いて変換後のテキストファイルの文字コードを指定します。変換前のテキストの文字コードはテキストファイルの内容から自動的に判断されるので、普通は -I を指定する必要はありません。文字コードは次のリストの形式で指定します。
|
|
Shift JIS (Microsoft 漢字コード)
|
|
|
-k は JISX0201 のいわゆる「半角カナ」を JISX0208 のいわゆる「全角カナ」に変換する機能です。インターネット上では半角カナを使わないように推奨されています。
lv の他、日本語専用ですが現在に至るまで広く使われている文字コード変換ツールとして、nkf があります。
|
$ nkf [{-e}|{-j}|{-s}] [<ファイル>]
|
|
|
-e, -j, -s は、それぞれ変換後の文字コードを EUC-JP, ISO-2022-JP, Shift JIS にすることを意味します。
| |

ここでは出てきませんが - マーカは file1 にしかない行を表します。
|
|