Sedハンドブック
はじめに
編集sedはストリームエディタ(Stream Editor)の略で、テキストの変換処理を行うための強力なツールです。パイプラインでの処理や、ファイルの一括編集に適しています。
sedの特徴
編集- 行指向の処理
- 正規表現によるパターンマッチング
- スクリプトによる自動編集
- 最小限のメモリ使用
基本構文
編集sed [オプション] 'コマンド' [入力ファイル] sed [オプション] -f スクリプトファイル [入力ファイル]
基本コマンド
編集置換(s/)
編集# 基本的な置換 sed 's/old/new/' # 各行の最初のマッチを置換 sed 's/old/new/g' # 各行のすべてのマッチを置換 sed 's/old/new/2' # 各行の2番目のマッチを置換 sed 's/old/new/ig' # 大文字小文字を区別せずに置換
削除(d)
編集sed '3d' # 3行目を削除 sed '1,5d' # 1-5行目を削除 sed '/pattern/d' # パターンにマッチする行を削除 sed '/start/,/end/d' # 開始パターンから終了パターンまでを削除
追加と挿入(a\, i\)
編集sed '2a\新しい行' # 2行目の後に行を追加 sed '2i\新しい行' # 2行目の前に行を追加 sed '/pattern/a\新しい行' # パターンマッチした行の後に追加
変更(c\)
編集sed '2c\置換後の行' # 2行目を完全に置換 sed '/pattern/c\新しい行' # パターンマッチした行を置換
高度な機能
編集アドレス指定
編集# 行番号による指定 sed '1,10s/old/new/g' # 1-10行目で置換 sed '2,+5s/old/new/g' # 2行目から5行分で置換 # パターンによる指定 sed '/start/,/end/s/old/new/g' # パターン間で置換 sed '/regex/!s/old/new/g' # パターンにマッチしない行で置換
保持スペース操作
編集# h, H (パターンスペース→保持スペース) sed 'h;n;H;x;s/\n/ /' # 2行を1行に結合 # g, G (保持スペース→パターンスペース) sed '/pattern/{h;d};$G' # パターンマッチした最後の行を最終行に移動 # x (パターンスペースと保持スペースの交換) sed 'x;1d;$G' # 行の順序を逆転
複数コマンドの実行
編集# セミコロンで区切る sed 's/old/new/;s/foo/bar/' # -eオプションを使用 sed -e 's/old/new/' -e 's/foo/bar/' # スクリプトファイルを使用 cat script.sed s/old/new/ s/foo/bar/
実践的な使用例
編集ファイル加工
編集# コメント行の削除 sed '/^#/d' config.txt # 空行の削除 sed '/^$/d' file.txt # 行頭と行末の空白を削除 sed 's/^[ \t]*//;s/[ \t]*$//' file.txt
テキスト整形
編集# 各行をダブルクォートで囲む sed 's/.*/"&"/' file.txt # カンマ区切りをタブ区切りに変換 sed 's/,/\t/g' data.csv # XMLタグの除去 sed 's/<[^>]*>//g' file.xml
プログラミング的な処理
編集# 行番号の付与 sed = file.txt | sed 'N;s/\n/\t/' # 特定パターン間の行を抽出 sed -n '/start/,/end/p' file.txt # 条件分岐 sed '/pattern/{s/old/new/;b};s/other/replace/' file.txt
高度な技術
編集ラベルとブランチ
編集# ラベルの定義と分岐 sed ':start s/old/new/ t start' file.txt # 条件付きブランチ sed '/pattern/{ s/old/new/ b next } s/other/replace/ :next' file.txt
サブシェルコマンドの実行
編集# 現在の日時を挿入 sed "s/DATE/$(date)/" template.txt # 外部コマンドの結果を使用 sed "s/VERSION/$(git describe)/" version.txt
付録A: sedイディオム集
編集A.1 テキスト処理イディオム
編集# 行の重複を除去(uniq相当) sed '$!N; /^\(.*\)\n\1$/!P; D' # 行の順序を逆転 sed '1!G;h;$!d' # 各行の前に行番号を付加 sed = file | sed 'N;s/\n/\t/' # 特定の行を2回繰り返す sed 'p;n' file # 奇数行を繰り返す sed 'n;p' file # 偶数行を繰り返す
A.2 ファイル加工イディオム
編集# 末尾に改行がないファイルに改行を追加 sed '$a\' # ファイルの先頭にヘッダーを追加 sed '1i\# Configuration File' config.txt # ファイルの末尾にフッターを追加 sed '$a\# End of file' config.txt # Windows形式の改行(CRLF)をUnix形式(LF)に変換 sed 's/\r$//'
A.3 プログラミング的イディオム
編集# 複数パターンの一括置換 sed -e 's/pattern1/replace1/g' \ -e 's/pattern2/replace2/g' \ -e 's/pattern3/replace3/g' # 特定範囲のみで置換を実行 sed '/start/,/end/{ s/old/new/g }' # 条件付き処理 sed '/pattern/{ /exclude/!{ s/old/new/g } }'
付録B: sedベストプラクティス
編集B.1 スクリプト構造
編集#!/bin/sed -f # メタ情報 # Author: name # Date: YYYY-MM-DD # Description: スクリプトの目的 # 初期処理 1{ # ヘッダー処理 i\# 処理開始 } # メイン処理 /pattern/{ # パターンに対する処理 s/old/new/g b next_label } # 終了処理 ${ # フッター処理 a\# 処理終了 }
B.2 保守性のための指針
編集- コメントを適切に使用する
# 複雑な正規表現には説明を付ける s/[0-9]{4}-[0-9]{2}-[0-9]{2}/& 00:00:00/ # 日付に時刻を追加
- 複雑な処理は分割する
# 複数の処理を論理的に分割 /pattern/{ # 前処理 s/prefix_// # メイン処理 s/old/new/ # 後処理 s/$/_suffix/ }
- エラー処理を含める
# 入力検証 /^[^0-9]*$/{ i\Error: Invalid input format d }
B.3 パフォーマンス最適化
編集- 効率的なパターンマッチング
# 悪い例 s/.*pattern.*/matched/ # 良い例 /pattern/s/.*/matched/
- 不要な処理を避ける
# 条件が合わない行はスキップ /pattern/!b # 必要な処理のみ実行 s/old/new/
- バッファの効率的な使用
# 必要な場合のみ保持スペースを使用 /pattern/{ h # 保持スペースに保存 d # 次の行へ } ${ g # 保持スペースから復元 }
B.4 デバッグとトレース
編集# デバッグ出力 /pattern/{ l # パターンスペースの内容を表示 /debug/p # デバッグ行を表示 } # 処理の追跡 /#DEBUG/{ i\=== Processing line === l i\================== }
これらのベストプラクティスとイディオムを適切に組み合わせることで、より保守性が高く、効率的なsedスクリプトを作成することができます。