💻 Bash
Linux/Unix 環境の標準シェル。コマンド自動化・バッチ処理・システム管理に不可欠。
📌 変数と特殊変数
| 記法 | 意味 |
|---|---|
VAR=value | 変数定義(=の前後にスペース不可) |
$VAR / ${VAR} | 変数参照 |
$0 | スクリプト自身のファイル名 |
$1 〜 $9 | 引数1番目〜9番目 |
$# | 引数の個数 |
$@ | 全引数(各引数を個別に展開) |
$* | 全引数(ひとつの文字列として展開) |
$? | 直前のコマンドの終了ステータス |
$$ | 現在のシェルのPID |
ARR=(a b c) | 配列定義 |
${ARR[0]} | 配列要素参照 |
${#ARR[@]} | 配列の要素数 |
📌 条件分岐
# if / elif / else
if [ "$VAR" = "hello" ]; then
echo "match"
elif [ $COUNT -gt 5 ]; then
echo "count > 5"
else
echo "other"
fi
# 主な比較演算子 (数値)
# -eq -ne -lt -le -gt -ge
# 主な比較演算子 (文字列)
# = != -z(空) -n(非空)
# ファイル判定
# -f(通常ファイル) -d(ディレクトリ) -e(存在) -r(読込可)
# case 文
case "$1" in
start) echo "starting" ;;
stop) echo "stopping" ;;
*) echo "unknown" ;;
esac
📌 ループ
# for ループ
for i in 1 2 3 4 5; do
echo "$i"
done
# C スタイル for
for (( i=0; i<10; i++ )); do
echo "$i"
done
# while ループ
while [ $COUNT -lt 5 ]; do
COUNT=$((COUNT + 1))
done
# ファイルを1行ずつ処理
while IFS= read -r line; do
echo "$line"
done < input.txt
📌 関数
# 関数定義
function greet() {
local name="$1" # localでスコープを限定
echo "Hello, $name!"
return 0 # 終了ステータス
}
greet "World" # 呼び出し
echo "exit: $?" # 終了ステータス確認
📌 パイプ・リダイレクト
| 記法 | 意味 |
|---|---|
cmd1 | cmd2 | cmd1の出力をcmd2の入力へ |
cmd > file | 標準出力をfileへ上書き |
cmd >> file | 標準出力をfileへ追記 |
cmd 2> err.log | 標準エラーをファイルへ |
cmd 2>&1 | 標準エラーを標準出力にマージ |
cmd < file | fileを標準入力として渡す |
cmd1 && cmd2 | cmd1成功時のみcmd2実行 |
cmd1 || cmd2 | cmd1失敗時のみcmd2実行 |
💡 よく使うコマンド
| コマンド | 用途 |
|---|---|
grep -rn pattern dir/ | ディレクトリ再帰検索 |
sed 's/old/new/g' file | 文字列置換 |
awk '{print $1}' file | 列抽出 |
find . -name "*.log" -mtime -7 | 7日以内に更新されたlogファイル |
xargs rm < list.txt | ファイル一覧を引数に渡してrm |
sort -k2 -n file | 2列目を数値昇順でソート |
uniq -c | 重複行カウント |
cut -d',' -f2 | CSV 2列目を取得 |
tr -d '\r' | Windows改行コード除去 |
wc -l file | 行数カウント |
📌 awk — テキスト処理の強力ツール
awk は行ごとにフィールド分割してパターンマッチ・集計・変換を行う。grep(検索)・sed(置換)と並ぶテキスト処理の三種の神器。
📐 基本構文
| コマンド | 用途 |
|---|---|
awk '{ action }' file | 全行に action を実行 |
awk 'pattern { action }' file | pattern に一致した行だけ action を実行 |
awk -F: '{ print $1 }' file | -F でフィールドセパレータを指定(ここでは :) |
awk -F',' -v OFS='\t' '{ print $2,$3 }' file | CSV を読んでタブ区切りで出力 |
awk 'BEGIN{…} {…} END{…}' file | 処理開始前・各行・処理終了後のブロックを定義 |
📦 組み込み変数
| 変数 | 意味 |
|---|---|
$0 | 行全体 |
$1, $2, … | 1番目・2番目のフィールド(スペース/タブ区切り) |
NF | 現在行のフィールド数。$NF で最終フィールド |
NR | 処理済み行番号(全ファイル通算) |
FNR | 現在ファイル内の行番号 |
FS | 入力フィールドセパレータ(デフォルト: スペース/タブ) |
OFS | 出力フィールドセパレータ(デフォルト: スペース) |
RS | 入力レコードセパレータ(デフォルト: 改行) |
FILENAME | 処理中のファイル名 |
🔍 パターン・フィルタ
| コマンド | 用途 |
|---|---|
awk '/error/' file | 正規表現にマッチする行を出力(grep 相当) |
awk '!/^#/' file | # 始まりの行を除外 |
awk '$3 > 100' file | 3列目が100より大きい行を出力 |
awk '$1 == "ERROR"' file | 1列目が "ERROR" の行を出力 |
awk 'NR>=3 && NR<=7' file | 3〜7行目を出力 |
awk '$0 ~ /pat/ && $2 > 0' file | 正規表現 AND 数値条件の複合フィルタ |
➕ 集計・演算
| コマンド | 用途 |
|---|---|
awk '{ sum += $1 } END { print sum }' file | 1列目の合計を出力 |
awk '{ sum += $1 } END { print sum/NR }' file | 平均を出力 |
awk '{ if($1>max) max=$1 } END{ print max }' file | 最大値を出力 |
awk '{ count[$1]++ } END { for(k in count) print k, count[k] }' file | 値ごとの出現回数を集計(連想配列) |
awk 'END{ print NR }' file | 行数カウント(wc -l 相当) |
💡 実践サンプル
# アクセスログからステータスコード別件数を集計
awk '{ count[$9]++ } END { for(s in count) print s, count[s] }' access.log | sort -k1
# CSVの2列目を合計(ヘッダ行スキップ)
awk -F',' 'NR>1 { sum += $2 } END { print "合計:", sum }' data.csv
# 特定フィールドを書き換えて出力(3列目を *2)
awk '{ $3 = $3 * 2; print }' file
# 重複行を除去(sort | uniq より手軽な場合)
awk '!seen[$0]++' file
# 複数ファイルを横断してファイル名付きで検索
awk '/ERROR/{ print FILENAME ":" NR ": " $0 }' *.log