← 学習トップに戻る 🏠 hideの部屋

💻 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 | cmd2cmd1の出力をcmd2の入力へ
cmd > file標準出力をfileへ上書き
cmd >> file標準出力をfileへ追記
cmd 2> err.log標準エラーをファイルへ
cmd 2>&1標準エラーを標準出力にマージ
cmd < filefileを標準入力として渡す
cmd1 && cmd2cmd1成功時のみcmd2実行
cmd1 || cmd2cmd1失敗時のみcmd2実行

💡 よく使うコマンド

コマンド用途
grep -rn pattern dir/ディレクトリ再帰検索
sed 's/old/new/g' file文字列置換
awk '{print $1}' file列抽出
find . -name "*.log" -mtime -77日以内に更新されたlogファイル
xargs rm < list.txtファイル一覧を引数に渡してrm
sort -k2 -n file2列目を数値昇順でソート
uniq -c重複行カウント
cut -d',' -f2CSV 2列目を取得
tr -d '\r'Windows改行コード除去
wc -l file行数カウント

📌 awk — テキスト処理の強力ツール

awk は行ごとにフィールド分割してパターンマッチ・集計・変換を行う。grep(検索)・sed(置換)と並ぶテキスト処理の三種の神器。

📐 基本構文

コマンド用途
awk '{ action }' file全行に action を実行
awk 'pattern { action }' filepattern に一致した行だけ action を実行
awk -F: '{ print $1 }' file-F でフィールドセパレータを指定(ここでは :)
awk -F',' -v OFS='\t' '{ print $2,$3 }' fileCSV を読んでタブ区切りで出力
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' file3列目が100より大きい行を出力
awk '$1 == "ERROR"' file1列目が "ERROR" の行を出力
awk 'NR>=3 && NR<=7' file3〜7行目を出力
awk '$0 ~ /pat/ && $2 > 0' file正規表現 AND 数値条件の複合フィルタ

➕ 集計・演算

コマンド用途
awk '{ sum += $1 } END { print sum }' file1列目の合計を出力
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

🔗 参考リンク