テクノロジー · 実用ガイド

sed -i が Linux では動き macOS で失敗?編集前に引数境界を証明する

sed の実装と正確な argv を特定し、変換を preview してから backup または temporary-file 方針を選びます。

ja sed argument boundary diagram
オリジナル編集イラスト: verify the sed implementation and argument boundary. Watch at Ease

sed -i が Linux では成功し macOS で失敗する場合、表示された command だけでは証拠が足りません。GNU と BSD 系 sed は suffix を異なる形で定義し、shell が token を決めます。

source を保存し、実装を確認して stdout を preview した後に backup または置換分岐を試すことで、portable 修正による破壊を防ぎます。

実装と正確な引数を保存

実行ファイルのパス、version、OS、shell、完全な command、生成された filename を記録します。すべてを quoting error と決めつけず、どの sed が引数を解析したかを証明します。

変更前に shell 変数と配列を展開します。Linux からコピーした command は、見た目が似ていても BSD 系 sed では token の境界が変わることがあります。

in-place suffix 規則を分離

GNU sed の -i suffix は任意です。suffix なしは backup を残さず、指定時は元ファイルを backup 名へ移します。-Ei と -iE は同じではありません。

FreeBSD manual は -i の後に extension を要求します。空の extension は backup なし、非空値は backup 名になります。extension を検証対象のデータとして扱います。

編集前に変換を preview

コピーに対して -i を外し、stdout を新しい temporary file へ書きます。入力との差分、行数、encoding、pattern の一致を確認します。

これで sed program と置換処理を分離できます。preview が誤っていれば、regex mode、escape、delimiter、newline を先に修正します。

限定された portable 戦略を選択

管理された環境では実装を一度判定し、明示的な backup suffix を持つテスト済み分岐を使います。portable script では検証済み temporary output を置換します。

別実装が拒否する sed --version だけを判定に使わないでください。失敗を処理できる実装テスト、build contract、または標準の temporary-file 手順を使います。

終了証拠と rollback を確認

no match、multiple match、空白を含む path、末尾 newline、既存 backup 名をテストし、各 runner の結果、exit code、backup policy を確認します。

最初は小さく展開します。意図した内容だけが変わり、不要な bytes が安定し、予期した files だけが存在して初めて成功です。失敗時は入力と argv を保存します。

ja sed preview and replacement diagram
オリジナル編集イラスト: preview and compare before replacing the source file. Watch at Ease