🐧 Linux 総合学習プラットフォーム
正規表現・テキスト処理 ・ 中級

パイプでつなぐ定番テキスト加工

テキスト処理の力は、小さなコマンドをパイプ | でつなぐと一気に高まります。cut で列を切り出し、tr で文字を置換・削除し、sort で並べ替え、uniq で重複をまとめ、wc で行数を数える、といった部品を組み合わせます。定番は sort してから uniq -c で出現回数を数える流れで、ログの集計などで多用します。例えば cut -d: -f1 /etc/passwd | sort | uniq でユーザー名を重複なく並べられます。1つ1つは単純でも、つなぐことで実用的な集計が作れます。

ここまで grep・sed・awk を個別に見てきた。だが、これらは一台ずつ使うために生まれたのではない。

Linuxのテキスト処理が本当に強さを見せるのは、小さなコマンドをパイプ | でつないで組み合わせたときだ。

パイプは、あるコマンドの出力(標準出力)を、そのまま次のコマンドの入力(標準入力)へ渡す仕組みで、この一連のつながりをパイプラインと呼ぶ。

🔗
たとえパイプラインは、職人を一列に並べた流れ作業だ。各人は単純な仕事だけをこなし、加工した品を隣へ手渡す。連ねることで複雑な仕事が仕上がる。

1つ1つのコマンドは単純な仕事しかしないが、それらを数珠つなぎにすることで、複雑な集計や抽出を一行で組み立てられる。「小さな道具を一つのことだけうまくやらせ、組み合わせて大きな仕事をする」というのが、Unix由来のテキスト処理の基本思想だ。

重要なのは、各コマンドが受け取るのも返すのも同じ「行の並んだテキスト」だという点だ。この共通の形式があるからこそ、道具を自由に並べ替えたり差し替えたりできる。

💡
ポイント各コマンドが受け取るのも返すのも、同じ「行の並んだテキスト」。この共通の形式があるから、道具を自由に並べ替えたり差し替えたりできる。

🧩 つなぐための部品には、何があるのか

パイプラインでよく使う部品をいくつか押さえておこう。

cut は行から特定の列(フィールド)を切り出す。cut -d: -f1 /etc/passwd のように、-d で区切り文字、-f で何列目かを指定する。複数列なら -f1,3 や範囲指定の -f1-3 も使える。

tr は文字を置換・削除する道具で、tr 'a-z' 'A-Z' で小文字を大文字に変換したり、tr -d ' ' で空白を消したり、tr -s ' ' で連続する空白を1つにまとめたりできる。

sort は行を並べ替え(数値順は -n、降順は -r)、uniq は隣り合う重複行をまとめる。

cut -d: -f1 /etc/passwd で1列目を切り出し、tr 'a-z' 'A-Z' で大文字化、sort で並べ替え、wc -l で行数を数える。

wc は行数・単語数・文字数を数え、とくに wc -l で行数を数える使い方が頻出だ。head と tail で先頭・末尾だけを取るのもパイプの定番だ。

これらを grep・sed・awk と組み合わせて、「絞る・取り出す・並べる・数える」を一筆書きにするのが基本になる。

🔢 なぜ sort を挟まないと、件数が狂うのか

もっともよく使う組み合わせの一つが、sort してから uniq -c で出現回数を数える流れだ。

awk取り出すsort並べるuniq -c数えるsort -rn並べ直すhead上位uniq は隣り合う重複しかまとめない → 先に sort で隣り合わせる

ここに見落としやすい急所がある。uniq は連続して並んだ重複しかまとめないので、先に sort で同じ行を隣り合わせてから渡す必要があるのだ。

つまずきuniq は連続して並んだ重複しかまとめない。先に sort で同じ行を隣り合わせてから渡さないと、件数が正しく出ない。

uniq -c を使うと、各行の前に出現回数が付く。たとえば cut -d: -f1 /etc/passwd | sort | uniq とすれば、ユーザー名を重複なく並べられる。

アクセスログからアクセス元の多い順を出したいなら、対象を取り出してから sort | uniq -c | sort -rn のようにつなぐのが王道で、最後の sort -rn(-r は降順、-n は数値順)で件数の多い順に並べ替える。

awk '{print $1}' access.log | sort | uniq -c | sort -rn | head で、アクセス元の上位だけをランキング表示できる。

たとえば awk '{print $1}' access.log | sort | uniq -c | sort -rn | head と書けば、アクセス元の上位だけをランキング表示できる。

この「取り出す → 並べる → 数える → 並べ直す → 上位を見る」という流れは、ログ分析でそのまま何度も使える集計の型なので、丸ごと覚えておくと応用が効く。

🪜 長い一行を、どう間違えずに組み立てるか

長いパイプラインは、いきなり全部を書こうとすると失敗する。こつは、左から1段ずつ足して、その都度結果を確かめながら組み立てることだ。

コツ長いパイプラインは左から1段ずつ足し、その都度結果を確かめながら伸ばす。完成形だけを目指さず中間出力を見るのが、確実で速い作り方だ。

まず cut だけ実行して列が正しく取れているか見て、次に | sort を足し、さらに | uniq -c を継ぐ、というように段階的に伸ばす。

たとえば「ログイン用シェルごとの利用人数」を出すなら、awk -F: '{print $NF}' /etc/passwd でまずシェルの列(最終フィールド)を取り、| sort で並べ、| uniq -c で数える、と一段ずつ確認しながら組めば、どこで意図とずれたかをすぐ特定できる。

完成形だけを目指さず、中間出力を見ながら伸ばすのが、確実で速い作り方だ。

⚠ つまずいたら、まずこれ

つまずきやすいのは、先ほど触れた「sort を省いて uniq を使う」ケースだ。重複行が離れて並んでいると uniq はまとめてくれず、件数が正しく出ない。

また、cut の -d で区切り文字を間違える(コロン区切りなのに既定のタブのままにするなど)と、列がずれて空の結果になる。

tr は引数に2つの文字集合を取って変換するが、削除したいときは -d を付けて集合を1つだけ渡す、という使い分けも混同しがちだ。

さらに、sort の数値順 -n を付け忘れると、10 が 9 より前に並ぶ「辞書順」になってしまい、件数の多い順のつもりが狂う、というのもありがちな落とし穴だ。

つまずきsort の数値順 -n を付け忘れると、10 が 9 より前に並ぶ「辞書順」になり、件数の多い順のつもりが狂う。

パイプの途中で結果がおかしくなったら、その手前までを実行して中間出力を確認するのが、原因切り分けの近道だ。エラーメッセージが出なくても結果が空、というときほど、段階確認が効く。

🛠 実務では、どこまでのことができるのか

実務では、ログ集計やデータの下ごしらえでパイプラインが日常的に活躍する。

エラーの種類ごとの件数を出す、アクセスの多いURLを順位付けする、設定ファイルから有効な行だけを抜き出して整形する。いずれも grep で行を絞り、cut や awk で列(フィールド)を取り、sort・uniq・wc で集計する、という部品の組み合わせで実現できる。

grep 'ERROR' app.log | awk '{print $4}' | sort | uniq -c | sort -rn は、エラー行を取り出し種別を数えて多い順に並べる分析を一行で表す。

たとえば grep 'ERROR' app.log | awk '{print $4}' | sort | uniq -c | sort -rn は、エラー行だけを取り出してその種別を数え、多い順に並べる、という一連の分析をたった一行で表している。

一つ一つは単純でも、切り出し、並べ替え、数えるという流れをつなぐことで、専用ツールを書かずに実用的な分析が作れる。

このパイプラインを自在に組み立てられることが、Linuxでのテキスト処理力そのものだと言ってよいだろう。grep・sed・awk の各コマンドは、パイプでつないで初めて本領を発揮する。

この項目に出てくる用語

パイプラインぱいぷらいん
| でコマンドをつなぎ、出力を次の入力へ渡す仕組み。
フィールドふぃーるど
1行を区切り文字で分けた1つ1つの列。

関連コマンド

cuttrsortuniqwc

▶ 学習アプリでこの続きを学ぶ・演習する