1. 👋 はじめに
「grep でファイルを検索できるようになったけど、もっと複雑なパターンで検索したい!」
「ログファイルから特定のデータだけ抜き出したい!」
「ファイルの中の文字列を一括で置換したい!」
そんなときに活躍するのが正規表現とsed・awkです!
ただし、正規表現は初心者には少し難しく感じるテーマです。この記事では**「なんとなく読める・書ける」レベルを目標**に、やさしく解説します🌟
この記事を読めば:
- ✅ 正規表現の基本パターンがわかる
- ✅ grep と組み合わせて使える
- ✅ sed で文字列を置換できる
- ✅ awk で列を自在に処理できる
2. 🔤 正規表現とは?
正規表現(Regular Expression / regex)は、文字列のパターンを表す特別な書き方です。
通常の検索:「error」という文字列を探す
↓
正規表現:「数字3桁のあとにハイフンが来る文字列」を探す
「ERRORまたはerrorまたはErrorを探す」
「行の先頭がAで始まる行を探す」
具体的なイメージ
🔍 正規表現を使わない検索
「田中」を含む行を検索 → そのまま「田中」で検索
🔍 正規表現を使った検索
「090-xxxx-xxxx 形式の電話番号」を検索
→ 090-[0-9]{4}-[0-9]{4} というパターンで検索
→ 090-1234-5678 も 090-9876-5432 も一発でヒット!
3. 📖 正規表現の基本パターン
① 普通の文字
普通の文字はそのまま検索されます。
grep "error" app.log # "error" を含む行を検索
grep "Alice" names.txt # "Alice" を含む行を検索
② .(ドット):任意の1文字
# a.c → a + 何か1文字 + c にマッチ
echo "abc" | grep "a.c" # ✅ マッチ
echo "axc" | grep "a.c" # ✅ マッチ
echo "ac" | grep "a.c" # ❌ マッチしない(間に1文字必要)
③ *:直前の文字の0回以上の繰り返し
# ab*c → a + bが0回以上 + c にマッチ
echo "ac" | grep "ab*c" # ✅ マッチ(bが0回)
echo "abc" | grep "ab*c" # ✅ マッチ(bが1回)
echo "abbbc" | grep "ab*c" # ✅ マッチ(bが3回)
④ ^(キャレット):行の先頭
# ^ERROR → ERRORで始まる行にマッチ
grep "^ERROR" app.log
# ERROR: something went wrong ← ✅ マッチ
# [INFO] ERROR occurred ← ❌ マッチしない(先頭がERRORでない)
⑤ $(ドル):行の末尾
# .log$ → .logで終わる行にマッチ
grep "\.log$" filelist.txt
# app.log ← ✅ マッチ
# app.log.bak ← ❌ マッチしない(.logで終わっていない)
⑥ [](文字クラス):指定した文字のどれか1つ
# [abc] → a または b または c の1文字にマッチ
echo "apple" | grep "[abc]" # ✅ マッチ(aがある)
echo "xyz" | grep "[abc]" # ❌ マッチしない
# [a-z] → 小文字アルファベット1文字
# [A-Z] → 大文字アルファベット1文字
# [0-9] → 数字1文字
# [^abc] → a・b・c 以外の1文字(^ は否定)
grep "[0-9]" memo.txt # 数字を含む行
grep "^[A-Z]" memo.txt # 大文字で始まる行
⑦ 拡張正規表現(ERE):+・?・{}・|
grep -E または egrep で使える拡張パターンです。
# + → 直前の文字の1回以上の繰り返し
grep -E "ab+c" <<< "abc" # ✅(bが1回以上)
grep -E "ab+c" <<< "ac" # ❌(bが0回はNG)
# ? → 直前の文字の0回または1回
grep -E "colou?r" <<< "color" # ✅(uが0回)
grep -E "colou?r" <<< "colour" # ✅(uが1回)
# {n} → 直前の文字をちょうどn回
# {n,m} → n回以上m回以下
grep -E "[0-9]{3}" <<< "123" # ✅ 数字3桁
grep -E "[0-9]{3}-[0-9]{4}" <<< "090-1234" # ✅ 電話番号パターン
# | → または(OR)
grep -E "ERROR|WARNING" app.log # ERRORまたはWARNINGを含む行
grep -E "cat|dog|bird" memo.txt # cat・dog・bird のどれかを含む行
よく使う正規表現パターン集
# バックスラッシュはエスケープだよ!
# メールアドレスを含む行
grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" data.txt
# IPアドレスを含む行
grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log
# 日付(YYYY-MM-DD形式)を含む行
grep -E "[0-9]{4}-[0-9]{2}-[0-9]{2}" log.txt
# 空行を除いた行
grep -v "^$" memo.txt # -v は「マッチしない行」を表示
# 数字だけの行
grep -E "^[0-9]+$" data.txt
4. 🔍 sed:ストリームエディタ
sed(Stream Editor)はファイルの内容をコマンドラインから編集できるツールです。正規表現と組み合わせることで、強力なテキスト処理ができます。
基本構文
sed 's/検索パターン/置換文字列/フラグ' ファイル名
# ↑s は substitute(置換)の意味
シンプルな置換
# 基本の置換(最初の1つだけ)
sed 's/Hello/Hi/' memo.txt
# 全て置換(g = global)
sed 's/Hello/Hi/g' memo.txt
# 大文字・小文字を区別しない(I オプション)
sed 's/hello/Hi/gI' memo.txt
# Hello・HELLO・hello すべてにマッチ
# 結果をファイルに上書き(-i オプション)⚠️
sed -i 's/Hello/Hi/g' memo.txt
# バックアップを取りながら上書き(おすすめ!)
sed -i.bak 's/Hello/Hi/g' memo.txt
# → memo.txt.bak にバックアップが作られる
正規表現を使った置換
# 数字を * に置換
sed 's/[0-9]/*/g' memo.txt
# 元:price: 1500円
# 後:price: ****円
# 行頭の空白を削除
sed 's/^[[:space:]]*//' memo.txt
# 行末の空白を削除
sed 's/[[:space:]]*$//' memo.txt
# 電話番号をマスク
sed 's/[0-9]\{2,4\}-[0-9]\{2,4\}-[0-9]{4}/***-****-****/g' data.txt
行の操作
# 特定の行を削除(d = delete)
sed '3d' memo.txt # 3行目を削除
sed '3,5d' memo.txt # 3〜5行目を削除
sed '/^#/d' config.txt # #で始まる行(コメント行)を削除
sed '/^$/d' memo.txt # 空行を削除
# 特定の行だけ表示(p = print、-n で他を非表示)
sed -n '3,5p' memo.txt # 3〜5行目だけ表示
sed -n '/ERROR/p' app.log # ERRORを含む行だけ表示
# 特定の行の前後に文字を追加
sed '/ERROR/i\--- エラー発生 ---' app.log # ERRORの前に追加
sed '/ERROR/a\--- 確認してください ---' app.log # ERRORの後に追加
複数の処理を一度に実行
# -e で複数の処理を指定
sed -e 's/Hello/Hi/g' -e 's/World/Linux/g' memo.txt
# セミコロンで区切ることもできる
sed 's/Hello/Hi/g; s/World/Linux/g' memo.txt
5. 🦅 awk:テキスト処理の万能ツール
awk は列単位でテキストを処理する強力なツールです。CSVやログの解析が得意です。
基本の考え方
awkはファイルを1行ずつ読み込んで処理します。各行を「列」に分解して操作するのが特徴です。
awk の処理イメージ
data.csv の中身:
Alice,25,Tokyo
Bob,30,Osaka
Charlie,22,Tokyo
1行目を読み込む → Alice,25,Tokyo
↓ カンマで分割
$1=Alice $2=25 $3=Tokyo
2行目を読み込む → Bob,30,Osaka
↓ カンマで分割
$1=Bob $2=30 $3=Osaka
… これを全行繰り返す
基本構文
awk 'パターン { アクション }' ファイル名
# パターン:条件(省略すると全行が対象)
# アクション:各行に対してやること
① 列を表示する
まずは一番よく使う「特定の列だけ表示する」操作から覚えましょう!
サンプルデータ(data.csv):
Alice,25,Tokyo
Bob,30,Osaka
Charlie,22,Tokyo
Diana,35,Nagoya
# 1列目(名前)だけ表示
awk -F "," '{print $1}' data.csv
# 出力結果
Alice
Bob
Charlie
Diana
# 1列目と3列目を表示
awk -F "," '{print $1, $3}' data.csv
# 出力結果
Alice Tokyo
Bob Osaka
Charlie Tokyo
Diana Nagoya
# 最後の列を表示($NF = 最後の列番号)
awk -F "," '{print $NF}' data.csv
# 出力結果
Tokyo
Osaka
Tokyo
Nagoya
② 区切り文字の指定(-F オプション)
# -F で区切り文字を指定する
awk -F "," # カンマ区切り(CSV)
awk -F ":" # コロン区切り
awk -F "\t" # タブ区切り
awk # スペース区切り(デフォルト)
スペース区切りの例:
echo "Alice 25 Tokyo" | awk '{print $2}'
# 出力結果
25
③ 条件でフィルタリング
特定の条件に合う行だけ処理することができます。
# 2列目(年齢)が30以上の行だけ表示
awk -F "," '$2 >= 30 {print $0}' data.csv
# 出力結果
Bob,30,Osaka
Diana,35,Nagoya
# 3列目が "Tokyo" の行の名前だけ表示
awk -F "," '$3 == "Tokyo" {print $1}' data.csv
# 出力結果
Alice
Charlie
# "ERROR" という文字を含む行だけ表示
awk '/ERROR/ {print $0}' app.log
# 出力結果(例)
2026-03-17 10:00:01 ERROR データベース接続に失敗しました
2026-03-17 10:05:23 ERROR タイムアウトが発生しました
④ 集計・計算
複数行にまたがる集計処理も得意です!
# 2列目(年齢)の合計を計算
awk -F "," '{sum += $2} END {print "合計:", sum}' data.csv
# 出力結果
合計: 112
# 2列目(年齢)の平均を計算
awk -F "," '{sum += $2; count++} END {print "平均:", sum/count}' data.csv
# 出力結果
平均: 28
# 行数を数える(NR = 現在の行番号)
awk 'END {print NR, "件"}' data.csv
# 出力結果
4 件
⑤ BEGIN と END:前後に処理を追加する
BEGIN { } → ファイルを読む前に1回だけ実行(ヘッダー表示などに使う)
{ } → 各行を読むたびに実行(メインの処理)
END { } → 全行読み終わった後に1回だけ実行(集計結果の表示などに使う)
awk -F "," '
BEGIN {
print "=== メンバー一覧 ==="
}
{
print $1, "さん(" $3 ")"
}
END {
print "=== 合計" NR "名 ==="
}
' data.csv
# 出力結果
=== メンバー一覧 ===
Alice さん(Tokyo)
Bob さん(Osaka)
Charlie さん(Tokyo)
Diana さん(Nagoya)
=== 合計4名 ===
⑥ アクセスログ解析の実例
実務でよく使うアクセスログ解析の例です。
サンプルログ(access.log):
192.168.1.1 - - [17/Mar/2026] "GET /index.html" 200 1234
192.168.1.2 - - [17/Mar/2026] "GET /about.html" 200 567
192.168.1.1 - - [17/Mar/2026] "POST /api/login" 404 89
192.168.1.3 - - [17/Mar/2026] "GET /index.html" 200 1234
192.168.1.2 - - [17/Mar/2026] "GET /contact" 500 0
# ステータスコード(9列目)を集計
awk '{print $9}' access.log | sort | uniq -c | sort -rn
# 出力結果
3 200
1 404
1 500
# IPアドレス(1列目)ごとのアクセス数を集計
awk '{print $1}' access.log | sort | uniq -c | sort -rn
# 出力結果
2 192.168.1.1
2 192.168.1.2
1 192.168.1.3
6. 🔗 grep・sed・awk をパイプでつなげる
これら3つをパイプで組み合わせると、複雑なデータ処理が1行で書けます!
# 例①:ERRORを含む行からタイムスタンプだけ抽出
grep "ERROR" app.log | awk '{print $1, $2}'
# 例②:アクセスログから特定のIPを除外して集計
grep -v "192.168.1.1" access.log | awk '{print $9}' | sort | uniq -c
# 例③:CSVの特定列を条件でフィルタして別ファイルに保存
awk -F "," '$3 == "Tokyo"' data.csv | sed 's/Tokyo/東京/g' > tokyo.csv
# 例④:ログから過去1時間のエラー数を数える
grep "$(date +%Y-%m-%d\ %H)" app.log | grep "ERROR" | wc -l
7. 📋 まとめ早見表
grep オプション一覧
| オプション | 意味 | 例 |
|---|---|---|
| (なし) | 基本検索 | grep "error" app.log |
-E |
拡張正規表現を使う | grep -E "ERROR|WARNING" app.log |
-v |
マッチしない行を表示 | grep -v "DEBUG" app.log |
-i |
大文字小文字を区別しない | grep -i "error" app.log |
-n |
行番号も表示 | grep -n "error" app.log |
-r |
ディレクトリを再帰的に検索 | grep -r "error" ./src/ |
-c |
マッチした行数を表示 | grep -c "error" app.log |
正規表現メタ文字一覧
| メタ文字 | 意味 | 例 | マッチする例 |
|---|---|---|---|
. |
任意の1文字 | a.c |
abc、axc、a1c |
* |
直前の文字の0回以上 | ab*c |
ac、abc、abbc |
+ |
直前の文字の1回以上(-E必要) | ab+c |
abc、abbc |
? |
直前の文字の0か1回(-E必要) | colou?r |
color、colour |
^ |
行の先頭 | ^ERROR |
ERRORで始まる行 |
$ |
行の末尾 | \.log$ |
.logで終わる行 |
[abc] |
a・b・cのどれか1文字 | [aeiou] |
母音1文字 |
[^abc] |
a・b・c以外の1文字 | [^0-9] |
数字以外 |
[0-9] |
数字1文字 | [0-9]{3} |
数字3桁 |
{n} |
n回の繰り返し(-E必要) | [0-9]{4} |
数字4桁 |
| |
または(-E必要) | cat|dog |
catまたはdog |
sed コマンド一覧
| コマンド | 意味 | 例 |
|---|---|---|
s/古い/新しい/ |
最初の1つを置換 | sed 's/Hello/Hi/' memo.txt |
s/古い/新しい/g |
すべて置換 | sed 's/Hello/Hi/g' memo.txt |
-i.bak |
バックアップ付きで上書き | sed -i.bak 's/a/b/g' memo.txt |
/パターン/d |
マッチした行を削除 | sed '/^#/d' config.txt |
-n '/パターン/p' |
マッチした行だけ表示 | sed -n '/ERROR/p' app.log |
3d |
3行目を削除 | sed '3d' memo.txt |
3,5p |
3〜5行目を表示 | sed -n '3,5p' memo.txt |
awk よく使うパターン一覧
| やりたいこと | コマンド例 |
|---|---|
| 1列目を表示 | awk '{print $1}' ファイル |
| CSV2列目を表示 | awk -F "," '{print $2}' ファイル |
| 最後の列を表示 | awk '{print $NF}' ファイル |
| 2列目が30以上の行 | awk '$2 >= 30' ファイル |
| 特定文字列を含む行 | awk '/ERROR/' ファイル |
| 2列目の合計 | awk '{sum+=$2} END{print sum}' ファイル |
| 行数を数える | awk 'END{print NR}' ファイル |
| ヘッダー・集計を付ける | awk 'BEGIN{...} {...} END{...}' ファイル |
8. 🎯 まとめ
| ツール | 得意なこと |
|---|---|
| 🔤 正規表現 | パターンを使った柔軟な文字列検索・マッチング |
| 🔍 grep + 正規表現 | ファイルから条件に合う行を抽出 |
| ✏️ sed | ファイルの文字列を置換・削除・行操作 |
| 🦅 awk | 列単位のデータ処理・集計・ログ解析 |
最初は難しく感じますが、よく使うパターンを少しずつ覚えていくのがコツです!まずは grep -E で正規表現検索に慣れて、次に sed の置換、最後に awk の集計、という順番で学んでいくとスムーズです🌟。しかし、なにより正規表現を知っていることが一番大事だと思います。見たときに「ああ、これは正規表現だな」と思えるようになってくれればうれしいです。
💬 質問や感想があれば、コメント欄でお気軽にどうぞ!
👍 役に立ったら、いいね&ストックをお願いします!
🎓 ここまで読んでくださって、本当にありがとうございました!
🔗 シリーズ記事
- 【第一回】基本操作 → ファイル操作・検索・エスケープ
- 【第二回】パーミッション・ユーザー管理・テキスト処理
- 【第三回】シェルスクリプト入門
- 【番外編A】正規表現とsed・awk入門(この記事)
- 【番外編B】パスを通すとは?PATH環境変数を完全解説
- 【番外編C】sudoコマンドを正しく理解しよう