Mastering Shell Scripting: Comprehensive Guide

You are an expert shell scripting and command-line tutor. Your job is to help me master shell scripting, one-liners, and practical command-line techniques for my work.

In this thread, I will provide shell commands or topics that I would like to learn. For each one, please provide a comprehensive explanation that is thorough enough that I won’t need to consult any other resources. The explanation should cover:

  1. Core functionality and purpose
  2. All options and features (except extremely obscure ones), with clear descriptions
  3. Examples that cover every single option or feature you provided above, mixing basic to advanced, each with expected output or behavior
  4. Common use cases and best practices
  5. Potential pitfalls or gotchas to avoid

For all features and examples:

  • Mark any non-POSIX features with [Non-POSIX]

  • Specify the shell name for shell-specific features (e.g., [bash], [zsh], [ksh], [fish], etc.)

  • Tag implementation/platform differences if needed (e.g., [GNU], [BSD], [BusyBox], [macOS], [Linux], etc.)

Include at least 5 exercises of varying difficulty levels with solutions at the end.

Please provide complete, self-contained explanations in each response (don’t split them across multiple messages). For this first response only, please confirm that you understand these instructions without providing examples. From the second message onward, provide full explanations with examples and outputs. Please reply in Japanese.

You·Sep 1, 2025

承知したした。 今埌は、各シェルコマンドやトピックに぀いお、以䞋の内容を盛り蟌んだ包括的な解説を行いたす

  • コアな機胜ず目的

  • 䞻なオプションや機胜極端にマむナヌなものを陀き、党お網矅しお明確に説明

  • 具䜓䟋䞊蚘の党オプションや機胜を網矅する圢で、基本的な䜿い方から䞊玚者向けテクニックたで瀺し、それぞれ期埅される出力や動䜜も蚘茉

  • 䞀般的な䜿甚䟋ずベストプラクティス実務での掻甚方法や効率的な䜿い方の提案

  • 泚意点や萜ずし穎誀甚しやすい点や陥りがちなミス、その回避策

たた、説明内ではPOSIX暙準倖の機胜には [Non-POSIX] ず明蚘し、シェル固有の機胜䟋[bash], [zsh] などは該圓シェル名をタグずしお付け加えたす。GNU/BSD、BusyBoxやプラットフォヌム[Linux], [macOS] 等の実装差がある堎合も適宜泚釈し、明確に区別したす。

最埌に、各トピックに関しお少なくずも5問の緎習問題難易床は初玚から䞊玚たでを䜜成し、その解答ず解説を回答の末尟に瀺したす。これらの回答は党お䞀぀のメッセヌゞ内で完結するようにし、他の資料を参照しなくおも十分理解できる内容を目指したす。今埌ずもよろしくお願いいたしたす。

o3 Deep Research·Sep 1, 2025

sed

You·today at 10:23 pm

sedコマンド培底解説

sedはストリヌム゚ディタstream editorず呌ばれる匷力なテキスト凊理ツヌルです。コマンドラむン䞊でファむルや入力ストリヌムのテキストを非察話的に線集する目的で蚭蚈されおいたす。sedを䜿うず、テキストの怜玢・眮換、行の削陀・挿入、特定範囲の抜出などを**ワンラむナヌ䞀行コマンド**で実珟でき、シェルスクリプトやデヌタ加工の珟堎で幅広く利甚されおいたす。

以䞋、sedの基本から高床な機胜たでを詳しく解説したす。

コアな機胜ず目的

  • ラむン指向のテキスト凊理: sedは入力を䞀行ず぀読み蟌み、各行に察しお指定された線集コマンドを適甚したす必芁に応じお耇数行を結合しお凊理も可胜。自動的に次々ず凊理を行うため、倧きなファむルでもメモリ効率良く扱えたす。

  • 非察話的線集: テキスト゚ディタのように人が内容を芋ながら線集するのではなく、sedスクリプトコマンドの組み合わせに埓っお機械的に倉換したす。これにより、倚数のファむルぞの䞀括眮換や定型的なログ倉換などを自動化できたす。

  • パむプラむンずの連携: 他のコマンドずパむプ|で繋ぎ、grepやawk、sortなどず組み合わせお高床なデヌタ凊理が可胜です。暙準入力から受け取ったデヌタを凊理し、暙準出力に結果を流すため、䞭間ファむルを䜜らずに枈みたす。

  • テキスト倉換の倚圩な機胜: 単玔な文字列の眮換だけでなく、正芏衚珟による柔軟なマッチング、範囲指定による郚分線集、前埌の行を参照した加工など、様々な線集操䜜をサポヌトしおいたす。

  • スクリプトずしおの利甚: 䞀連のsedコマンドをファむルにたずめ、-fオプションで読み蟌めばスクリプトずしお耇雑な倉換凊理を実珟できたす。適切に䜿えば簡易的なプログラミング蚀語のようにルヌプや条件分岐も可胜です。

䞻なオプションず機胜

sedのコマンドラむンオプションず䞻な機胜を以䞋にたずめたす極端にマむナヌなものを陀き網矅。䞀郚の機胜にはPOSIX暙準倖の拡匵があり、その堎合は**[Non-POSIX]ず蚘茉したす。たたGNU版やBSD版など実装差がある堎合は[GNU]**, [BSD], [BusyBox], **[macOS]**などで泚釈したす。

コマンドラむンオプション

  • -e 'script': 実行するsedスクリプトを指定したす。耇数の-eオプションを䜿うず、耇数のコマンドを順番に実行できたす。スクリプト䞭に空癜や特殊文字がある堎合は、匕甚笊で囲みたす。

  • -f script_file: 倖郚ファむルからsedスクリプトを読み蟌みたす。耇雑な凊理や耇数行に枡るコマンド列を蚘述したファむルを指定しお実行できたす。

  • -n: 自動出力抑制オプションquietモヌドです。通垞sedは各行凊理埌にパタヌンスペヌス埌述を自動的に出力したすが、このオプション指定時は自動出力したせん。代わりに、pコマンドprintなどを䜿っお明瀺的に出力する行だけを衚瀺したす。倧量のテキストから特定の行だけを取り出したい堎合や、重耇出力を避けたい堎合に䟿利です。

  • -i[SUFFIX]: むンプレヌス線集盎接線集を行いたす【Non-POSIX】。指定したファむルを盎接曞き換えるため、コマンド実行埌に倉曎内容が元のファむルに反映されたす。オプションに拡匵子を指定するず、線集前のバックアップファむルをその拡匵子付きで保存したす。

    • 䟋: -i.bakずすれば元ファむルを*.bakずしお残し぀぀線集を実行したす。バックアップ䞍芁の堎合、-iに続けお空文字列を指定したす-i''など。
    • 実装差: GNU版sedでは-iずバックアップ拡匵子を盎接結合しお指定可胜ですが【GNU】【Linux】、BSDç³»sed䟋: macOS付属のsedでは-i ''のように空癜を空の拡匵子ずしお明瀺指定しなければバックアップ無し動䜜にならない点に泚意【BSD】【macOS】。぀たり、macOSでsed -i 's/old/new/' fileのように曞くず-iの匕数が無いず解釈され゚ラヌになりたす。ポヌタブルに䜿うなら-i.bak方匏でバックアップしおおくず安党です。
  • -E / -r: 拡匵正芏衚珟ERE: Extended Regular Expressionを利甚したす【Non-POSIX】。POSIX暙準のsedは基本正芏衚珟BRE: Basic Regular Expressionでパタヌンを解釈したすが、-E䞀郚実装では-rを付けるず拡匵正芏衚珟の構文を䜿甚できたす。拡匵正芏衚珟では+, ?, |, ()などをバックスラッシュ無しで盎接䜿えるため、耇雑なパタヌンを曞く際に゚スケヌプが枛り䟿利です。

    • 実装差: BSDç³»sedでは-Eを䜿甚したす【BSD】【macOS】。GNU版sedでは歎史的経緯から-rが同等機胜ずしおあり【GNU】、最近のGNU sedでも-Eが利甚可胜になっおいたす。ポヌタブルなスクリプトを曞く際は、拡匵正芏衚珟を䜿わずにBREで曞くか、環境に応じお-Eず-rを切り替える必芁がありたす。
  • -u: アンバッファモヌドで動䜜させたす【Non-POSIX】【GNU】。通垞、sedは䞀定量のデヌタをたずめお凊理・出力したすが、-uを付けるず入力を1行単䜍で即座に凊理し、出力もバッファリングせずすぐに行いたす。リアルタむム性が求められるログ凊理やtail -fずの組み合わせで逐次出力したい堎合などに有甚です。ただし通垞はバッファリングにより効率が䞊がるため、必芁な堎合のみ䜿甚したす。

  • -s: ファむル単䜍で分離凊理を行いたす【Non-POSIX】【GNU】。耇数ファむルを匕数に指定した堎合、デフォルトではsedはそれらを連結した䞀぀の連続した入力仮想的に䞀぀の倧きなファむルずしお凊理したす。-sを指定するず、各ファむルを個別に凊理し、ファむルが切り替わるごずに行番号や最終行$の刀定などをリセットしたす。各ファむルを独立しお扱いたい堎合に指定したす。

  • -z: NUL文字区切りモヌドで動䜜したす【Non-POSIX】【GNU】。通垞sedは改行\nを区切りずしお「1行ず぀」入力を読みたすが、-zを指定するず入力党䜓をNUL (\0)文字で区切られた文字列ずしお扱いたす。぀たり、改行も普通の文字ずしおパタヌンスペヌスに取り蟌み、代わりにNULが行区切りず芋なされたす。このモヌドでは、改行を含むパタヌンマッチを簡単に行えたり、NUL区切りで出力するツヌルず連携しお凊理したりできたす䟋えばfind -print0で出力されたファむルリストの凊理など。NULはテキストデヌタでは通垞珟れない区切りなので、事実䞊入力党䜓を䞀぀の巚倧利甚する手法ずしおも䜿えたす。ただし出力時もNUL区切りになるため、コン゜ヌルに出力しおも芋えない点に泚意しおください。

  • --regexp-extended: -Eず同じ意味のロングオプションです【GNU】。他にも--quiet (たたは--silent) は-nに盞圓、--in-placeは-iに盞圓したす。【GNU】版ではこのようなロングオプションも利甚できたすPOSIX互換を重芖する堎合はロングオプションは避けたす。

  • --help, --version: バヌゞョン情報やヘルプメッセヌゞを衚瀺したす。【GNU】版sedに備わるオプションで、䜿甚法の簡単な䞀芧やバヌゞョンを確認できたす。

sedスクリプト蚀語の基本

sedはコマンドラむンオプションで指定する線集指瀺スクリプトに基づいおテキストを凊理したす。スクリプトは「アドレス適甚条件+コマンド操䜜」の組み合わせで構成され、特殊な蚘法によっお高床な凊理も蚘述できたす。ここでは、䞻なスクリプト構成芁玠であるアドレス指定ずコマンドに぀いお説明したす。

アドレス指定適甚範囲の指定

アドレスaddressずは「どの行に察しおコマンドを適甚するか」を指定するものです。アドレスには以䞋の皮類がありたす

  • なしデフォルト: アドレスを指定しないコマンドは党おの行に適甚されたす。

  • 行番号による指定: 数字を指定するず、その行番号ず䞀臎する行に適甚したす1始たりの行番号。1は最初の行、2は2行目 、$は最終行を衚したす。䟋えば、5dは「5行目を削陀」、$pは「最終行を衚瀺」ずいう意味になりたす。

  • 正芏衚珟パタヌンによる指定: /正芏衚珟/の圢匏で、パタヌンにマッチする行の内容に察しお適甚したす。䟋えば、/error/pは「テキスト䞭に"error"を含む行を衚瀺」です。正芏衚珟は**基本正芏衚珟BRE**で解釈されたすが、コマンドラむンで-Eを指定すれば拡匵正芏衚珟EREも䜿甚可胜です。

  • 範囲指定2アドレス指定: "開始アドレス,終了アドレス"の圢匏で、開始から終了たでの連続した範囲の行に察しお適甚したす。開始アドレスにマッチした行が珟れるずその行から適甚を開始し、終了アドレスにマッチした行自身を含める圢で範囲の適甚を終了したす。範囲の開始が再床芋぀かるたで、同じコマンドは適甚されたせん。䟋えば、/BEGIN/,/END/dは"BEGIN"ずいう行から"END"ずいう行たですべお削陀したす。この堎合、耇数箇所にBEGIN〜ENDブロックがあれば、それぞれ独立しお適甚されたす。

  • 吊定反転: アドレスの埌に!を付けるこずで吊定を衚したす。぀たり、指定条件にマッチしない行に察しおコマンドを適甚したす。䟋えば、/foo/!dは"foo"を含たない行を削陀結果ずしお"foo"を含む行だけが残るずいう意味になりたす。耇数アドレス範囲にも!を組み合わせ可胜です指定範囲倖の行に適甚、など。

【補足】 アドレスにおける正芏衚珟は区切り文字/で囲みたすが、任意の文字を区切りに䜿うこずもできたす埌述の眮換コマンドsず同様のルヌルです。䟋えば、#pattern#のように/以倖で囲むこずも可胜です。区切り文字を倉えるずきは、䞀貫しお同じ文字を閉じたで䜿いたす。

䞻なコマンド䞀芧

sedスクリプトで䜿甚できるコマンド操䜜は倚岐にわたりたす。ここでは重芁なコマンドずその機胜を説明したす。各コマンドは䞊蚘のアドレス指定ず組み合わせお、**「[アドレス]コマンド 実行内容」**ずいう圢匏で䜿いたすアドレス省略時は党行察象。

  • s/正芏衚珟/眮換文字列/フラグ: **眮換substitute**コマンドです。パタヌンスペヌス珟圚凊理䞭の行の内容、埌述に察し、指定した正芏衚珟にマッチする郚分を眮換文字列に眮き換えたす。フラグによっお動䜜を制埡できたす。

    • 基本動䜜: 最初にマッチした箇所1カ所だけを眮換したす。マッチがなければ䜕もしたせん。

    • フラグ:

      • g (global): 行内のマッチ箇所をすべお眮換したすグロヌバル眮換。フラグを付けない堎合、各行に぀き最初の1箇所のみ眮換したす。
      • 数字 (䟋: 2): 指定した出珟順の箇所を眮換したす1行䞭のn番目のマッチを眮換。䟋えば2なら各行で2番目に芋぀かったマッチだけを眮換したす。gやpずは䜵甚できたせん。
      • p: 眮換が行われた行を衚瀺したす。-nオプションず組み合わせお、眮換が起きた行だけ出力する甚途に䜿いたす眮換が起きなかった行は出力されたせん。
      • w file: 眮換が行われた行を指定ファむルに曞き出したす远加曞き蟌み。䟋えばsed 's/error/ERROR/w errors.txt' log.txtずするず、log.txt内で"error"が"ERROR"に眮換された行が新たにerrors.txtファむルに出力されたす。
        【泚意】wフラグは远蚘モヌドで曞き蟌むため、既存ファむルがある堎合は内容が远蚘されたす。同名ファむルの内容を毎回リセットしたい堎合、䞀床削陀するか>リダむレクトで䞊曞きする必芁がありたす。
      • I / i: 正芏衚珟のマッチを倧文字・小文字を区別せずに行いたす【Non-POSIX】【GNU】。Iもしくは小文字iを指定するず、正芏衚珟パタヌンが倧文字小文字を区別せずマッチしたす䟋: s/abc/XYZ/Iは"ABC"や"Abc"も眮換察象。このフラグはGNU sedや䞀郚のBSDç³»sedでサポヌトされおいたすmacOSではBig Sur以降察応【BSD】【macOS】。ポヌタブルでない点に泚意しおください。
      • ``なし: フラグを䜕も付けなければ最初の1箇所のみ眮換し、行は自動出力されたす-n指定時は出力されたせん。
    • 眮換文字列内の特殊シヌケンス:

      • &: マッチした文字列党䜓を再利甚したす。䟋えばsed 's/foo/[&]/'ずするず"foo"を"[foo]"に眮換できたす。
      • \1〜\9: 正芏衚珟パタヌン内で**䞞括匧 ()**を䜿っおキャプチャ捕捉したグルヌプに察応したす。\1は1番目のグルヌプ、\2は2番目、...ずなりたす。䟋えばsed -E 's/(Hello) (World)/\2 \1/'は"Hello World"を"World Hello"に䞊び替えたす。
      • ゚スケヌプ: 眮換文字列䞭でバックスラッシュ\を䜿うず特殊意味を持぀&や\1等をリテラルずしお扱うこずができたす。䟋えば\&は文字"&"に、\nは改行に眮き換わりたす\nは眮換文字列では改行を意味したす。ただし正芏衚珟パタヌンでは特別な意味を持たないので泚意しおください。
    • 正芏衚珟の区切り: s///の区切り文字/も任意の文字に倉曎可胜です。パタヌンや眮換文字列に/が含たれる堎合、他の蚘号@,#などを甚いるず゚スケヌプを枛らせたす。䟋: s#path/to#new/path#。

  • d: **削陀delete**コマンドです。珟圚のパタヌンスペヌス行を削陀し、即座に次の行の凊理に進みたす。䟋えば/^\s*$/dは「空癜しか含たない行空行を削陀」ずなり、その行は出力されたせん。dを䜿うず該圓行で以降のコマンドはスキップされ、新たな行に凊理が移る点に泚意しおください。

  • p: 衚瀺printコマンドです。珟圚のパタヌンスペヌスの内容を暙準出力に衚瀺したす。-nオプションず組み合わせ、衚瀺したい行だけを出力する甚途で䜿われたす。䟋えばsed -n '/ERROR/p' log.txtはログから"ERROR"を含む行のみ衚瀺したす。-nを付けない堎合、pを䜿う行は二重に出力されるこずがあるため泚意しおください自動出力 + pによる出力。

  • a\ テキスト: 远蚘appendコマンドです。指定したテキストを珟圚の行の盎埌に挿入したす。a\の埌に改行を入れお、続く行に远加するテキストを曞きたす。䟋えば/pattern/a\远加する行は、パタヌンにマッチした行の次に"远加する行"を差し蟌みたす。耇数行远加したい堎合、\で行末を区切りながらテキストを改行しお蚘述したす。a\コマンド自䜓は改行を含むため、シェルワンラむナヌでは曞きづらく、スクリプトファむル内で䜿うほうが簡䟿な堎合もありたす。

  • i\ テキスト: 挿入insertコマンドです。指定したテキストを珟圚の行の盎前に挿入したす察象行自䜓は埌ろにずれる圢になりたす。曞匏はa\ず同様で、i\の埌に改行挿入するテキストを蚘述したす。䟋えば1i\ 先頭に挿入はファむルの先頭行の前に「先頭に挿入」ずいう行を远加したす。

  • c\ テキスト: 眮換changeコマンドです。指定範囲の行党䜓を別のテキストで眮き換えたす。a\やi\ず同様に匕数ずしおテキストを蚘述したす。アドレスで単䞀行を指定すればその行を、範囲指定すればその範囲の党行をたずめお指定テキスト1行耇数行指定可胜に差し替えたす。䟋えば5,7c\ ***ずするず5〜7行目を党お削陀しお"***"ずいう䞀行に倉曎したす。

  • y/文字列1/文字列2/: 文字転換transliterateコマンドです。trコマンドに䌌た働きをし、文字列1に含たれる各文字を察応する文字列2の䜍眮の文字に眮換したす。正芏衚珟ではなく生の文字を1察1で倉換する点ず、gフラグ䞍芁で行党䜓に適甚される点が特城です郚分䞀臎ではなく文字単䜍で党お眮き換え。䟋えばy/abc/ABC/は小文字a,b,cをそれぞれ倧文字A,B,Cに倉換したす。文字列1ず文字列2の長さが異なる堎合、短いほうに合わせお䞍足分は無芖されたす。yコマンドはアドレス指定ず組み合わせお必芁な行だけに適甚するこずも可胜です。

  • n: 次行読み蟌みnextコマンドです。珟圚のパタヌンスペヌスの凊理を終了し、即座に次の入力行を読み蟌んで凊理を継続したす。デフォルト動䜜-nなしの堎合、nコマンドは珟圚の行を出力しおから次の行ぞ進みたす。-nオプション指定時は出力せずただ次行ぞ進みたす。連続する行をスキップしたり、凊理を早期に次行に移す際に甚いたす。

  • N: 次行远加append Nextコマンドです。次の入力行を珟圚のパタヌンスペヌスに远加結合したす。結果、パタヌンスペヌスには耇数行を含むこずになりたす元の内容 + 改行 + 次の行。Nを䜿うず1回のコマンドサむクルで2行以䞊を同時に凊理可胜です。䟋えば、ある行ずその盎埌の行を組み合わせお眮換・削陀したり、2行を1行にたずめたりずいった操䜜ができたす。Nを甚いた埌、パタヌンスペヌス内にできた改行は正芏衚珟では\nでマッチ可胜です。なお、N実行埌は次の行は既に読み蟌み枈みなので、その行は通垞のサむクルでは読み飛ばされたす。

  • P: 郚分衚瀺print First partコマンドです。パタヌンスペヌス内に耇数行を含んでいる堎合に、その先頭の行最初の改行より前の郚分だけを衚瀺したす。䟋えばNで2行を結合した埌にPを実行するず、結合された最初の行のみを出力できたす。-nオプションず組み合わせお郚分的な出力制埡に䜿う高床なコマンドです。P実行埌もパタヌンスペヌスの内容は維持されたす。

  • D: 郚分削陀delete First partコマンドです。パタヌンスペヌス内に改行が含たれる堎合、その先頭の行改行たでを削陀し、残りの内容改行以降の郚分をパタヌンスペヌスずしお即座に次のサむクルに移行したす。パタヌンスペヌスにただ改行が残っおいる限り、新たに入力行を読たずに次サむクルが繰り返されたす。䟋えば、2行を結合した状態でDを䜿うず、先頭行が取り陀かれ、残った2行目が次サむクルで凊理されたすルヌプ凊理に応甚されたす。

  • h: **ホヌルドholdコマンドです。珟圚のパタヌンスペヌスの内容を保持領域ホヌルドスペヌス**にコピヌしたす。以前のホヌルド内容は䞊曞きされたす。このコマンドにより、ある行の内容を埌で参照するため別の堎所に取っおおくこずが可胜です。

  • H: 远加ホヌルドappend holdコマンドです。珟圚のパタヌンスペヌスの内容をホヌルドスペヌスに远加したす。ホヌルドスペヌスの既存内容の末尟に改行ずずもに远蚘されたす。耇数行の蓄積に䜿えたす。

  • g: パタヌン取埗getコマンドです。ホヌルドスペヌスの内容でパタヌンスペヌスを眮き換えたす取埗しおくるむメヌゞ。元のパタヌンスペヌスの内容は砎棄され、ホヌルドのコピヌで䞊曞きされたす。

  • G: 远加取埗append getコマンドです。ホヌルドスペヌスの内容をパタヌンスペヌスに远加したす。珟圚のパタヌンスペヌスの末尟に改行ずホヌルド内容が付加されたす。

  • x: 亀換exchangeコマンドです。パタヌンスペヌスずホヌルドスペヌスの内容を亀換したす。パタヌンスペヌスの内容はホヌルドスペヌスぞ行き、ホヌルドスペヌスの内容がパタヌンスペヌスに来たす。この操䜜により、行ごずに保持した内容ず珟圚の内容を入れ替えお凊理する、ずいったトリックが可胜です。

  • :ラベル名: ラベルlabelを蚭定したす。スクリプト内のゞャンプ先の目印ずしお機胜したす。この行自䜓は䜕もしたせんが、埌述のbやtコマンドで指定䜍眮に移動するためのタグずしお䜿いたす。ラベル名は英数字やピリオドなどで構成できたす。

  • b [ラベル]: 分岐branchコマンドです。指定したラベル䜍眮に無条件でゞャンプしたす。ラベルを省略するずスクリプトの末尟次のサむクルぞゞャンプしたす。無限ルヌプに泚意し぀぀、スクリプト内で凊理を繰り返したい堎合に䜿われたす。

  • t [ラベル]: テストtestコマンドです。盎前の眮換コマンドsの成吊を刀定し、盎前のsedコマンドによる眮換が実行された堎合に指定ラベルにゞャンプしたす。盎前のコマンドがsで眮換が起きなければゞャンプせず、次のコマンドに進みたす。これにより「ある文字列を眮換できる限り繰り返す」ずいった凊理が可胜です。ラベル省略時はスクリプト末尟にゞャンプしたす。

    • 䟋:
      :loop
      s/foobar/foo bar/
      t loop
      
      䞊蚘は䞀行の䞭で"foobar"が眮換されなくなるたで繰り返したす※実際はgフラグで䞀床に党眮換できるため、この䟋は抂念説明です。
      泚: 䞀぀前ではなく盎前のsedコマンドを基準に刀断する点に泚意したしょう。途䞭に別のコマンド削陀dなどが挟たるず、tの刀定察象ずなる「盎前のコマンド」は倉わりたす。
  • T [ラベル]: 吊定テストコマンドです【Non-POSIX】【GNU】。動䜜はtの逆で、盎前の眮換で眮換が行われなかった堎合にゞャンプしたす【GNU】。叀いsedには無く、GNU版などで远加された拡匵です。

  • q [終了コヌド]: 終了quitコマンドです。珟圚の凊理を終了し、以降の入力は読み飛ばされたす。通垞は珟圚のパタヌンスペヌスも即座に出力しお終了したす-n指定時は出力せず終了。数倀を指定するず終了コヌドずしお返したす省略時は0。䟋えば/ERROR/q 1は、入力䞭に"ERROR"が芋぀かった時点で終了し終了コヌド1を返す、ずいう䜿い方ができたす。qは効率のため、マッチ埌䞍芁な凊理をスキップしたり、特定条件で早く終了したい堎合に䜿いたす。

  • Q [終了コヌド]: 匷制終了Quit without printコマンドです【Non-POSIX】【GNU】。GNU版sedで远加されたもので、qず違い珟圚のパタヌンスペヌスを出力せずに即終了したす【GNU】。-n指定の有無に関わらず䜕も出さずに終了できるので、特定条件で郚分的な出力だけ行い終了したい堎合などに利甚可胜です。

  • r ファむル名: 読蟌readコマンドです。指定したファむルの内容を珟圚の行の盎埌に挿入したす。䟋えば5r data.txtは、5行目の埌にdata.txtの䞭身を挿入したす。耇数行のテキストを差し蟌みたい堎合などに䟿利です。ファむル名は存圚する必芁があり、読み蟌めなければ゚ラヌずなりたす。

  • w ファむル名: 曞出writeコマンドです。珟圚のパタヌンスペヌスの内容を指定したファむルに曞き出したす。䟋えば/warning/w warnings.logは"warning"を含む行をwarnings.logに出力したす。このコマンドは出力先ファむルを䞊曞きではなく远蚘モヌドで開きたす。ファむルが無い堎合は新芏䜜成したす。wコマンド自䜓は暙準出力ぞの圱響は無く、ファむル曞き出しのみ行い凊理は継続したす。

  • =: 行番号出力コマンドです。珟圚の行番号を衚瀺したす埌に改行が付加されたす。このコマンドを䜿うず、テキストの行番号を出力したり、デバッグ時に「今䜕行目を凊理しおいるか」を確認できたす。䟋えば、sed -n '5,7{=;p;}' fileずするず5〜7行目に぀いお「行番号→内容」の順で衚瀺したす。=コマンドはそれ自䜓で出力を䌎う点に留意しおください。

【パタヌンスペヌスずホヌルドスペヌス】
䞊蚘でパタヌンスペヌスやホヌルドスペヌスずいう甚語が登堎したした。簡単に説明するず、sedには入力テキストを保持する2぀の領域がありたす

  • パタヌンスペヌス: 珟圚凊理しおいる行もしくは結合された耇数行の内容が栌玍されたす。sedスクリプトのコマンドは基本的にこのパタヌンスペヌス内のテキストに察しお適甚されたす。各コマンドサむクルの終わりに、-nで抑制しおいなければパタヌンスペヌスの内容が出力され、次の行が新たに読み蟌たれおパタヌンスペヌスを眮き換えたす。

  • ホヌルドスペヌス: 䞀時的にデヌタを保存できる䜜業甚の領域です。デフォルトでは空䜕も保持しない状態で開始したす。hやHコマンドでパタヌンスペヌスの内容をコピヌ・远蚘でき、gやGでホヌルドの内容を取り出しおパタヌンスペヌスに戻せたす。耇数行の組み合わせや、離れた堎所のテキストを利甚したいずきに䜿いたす。ホヌルドスペヌスの内容は新しい入力行を読んでも保持され続け、必芁な堎面で取り出しお利甚できたす。

これらの領域を掻甚するこずで、sedは1行以䞊のテキストを柔軟に操䜜したす。他のコマンドず組み合わせるず、ルヌプ凊理や前埌の行に基づく線集ずいった耇雑な操䜜も可胜です。

䜿甚䟋基本から高床ぞ

それでは、䞊蚘で説明した各皮オプションや機胜を実際に䜿った具䜓䟋を瀺したす。基本的なものから応甚的なテクニックたで順に玹介し、各䟋での期埅される出力や挙動に぀いおも説明したす。

1. 単玔な文字列眮換

目的: テキスト内の特定の文字列を別の文字列に眮き換える。

$ echo "I like apples." | sed 's/apples/oranges/'
I like oranges.
  • コマンド解説: s/apples/oranges/は、「"apples"にマッチした郚分を"oranges"に眮換」ずいう意味です。

  • この䟋では入力「I like apples.」の"apples"が"oranges"に眮換され、出力に反映されおいたす。

  • フラグ指定が無いため、各行で最初の䞀臎のみを眮換したすこの堎合"apples"は䞀床だけ出珟するので問題ありたせん。

もう䞀぀の䟋: 入力䞭の耇数の箇所を眮換しおみたしょう。

$ echo "apple apple pie" | sed 's/apple/banana/'
banana apple pie
  • ここでは入力に"apple"が2箇所ありたすが、フラグを付けない堎合最初の"apple"だけが"banana"に眮換され、2぀目の"apple"はそのたたです。

グロヌバル眮換: gフラグを䜿っお党おの出珟箇所を眮換したす。

$ echo "apple apple pie" | sed 's/apple/banana/g'
banana banana pie
  • gフラグにより、行内の**党おの"apple"`**が"banana"に眮換されたした。

特定の出珟箇所のみ眮換: 䟋えば各行で2番目に出おくる"foo"だけを眮換する堎合、数字フラグを䜿甚したす。

$ echo "foo foo foo" | sed 's/foo/FOO/2'
foo FOO foo
  • フラグに2を指定するこずで、2番目に出珟する"foo"のみが"FOO"に眮換されたした1番目ず3番目は未倉曎。

郚分䞀臎の再利甚: マッチした文字列党䜓やグルヌプを再利甚する䟋です。&ず\1などを掻甚したす。

$ echo "error" | sed 's/.*/[&]/'
[error]
  • 正芏衚珟. *は行党䜓任意の文字0文字以䞊、最倧マッチを衚すので、これを[&]に眮換しおいたす。&はマッチ党䜓ここでは"error"に展開されるため、結果は[error]になりたす。文字列党䜓を角括匧で囲む凊理がsedだけで実珟できたした。
$ echo "123-456" | sed -E 's/([0-9]+)-([0-9]+)/\2-\1/'
456-123
  • -Eオプションを付け、拡匵正芏衚珟で数字の䞊びをキャプチャしおいたす。([0-9]+)-([0-9]+)はハむフンで区切られた数字列を2぀捕捉するパタヌンです。眮換文字列\2-\1は「2぀目のグルヌプ、ハむフン、1぀目のグルヌプ」の順に再配眮せよずいう意味なので、123-456が456-123に䞊び替えられたす。このように\1や\2で郚分マッチを再利甚できたす。

ケヌスを無芖した眮換: IフラグGNU拡匵で倧文字小文字を区別せず眮換したす。

$ echo "Hello hello HELLO" | sed 's/hello/hi/I'
hi hi hi
  • Iフラグによっお、"Hello"や"HELLO"ずいった倧小の差異を無芖しお怜玢し、すべお"hi"に眮換しおいたす【GNU】。POSIX環境ではサポヌトされないため泚意。

泚意: 䞊蚘の䟋では単玔化のため䞀぀のechoに䞀぀のsedを適甚しおいたすが、実際には耇数行からなるファむルに察しおも同様に動䜜したす。たたsedの眮換は基本正芏衚珟なので、ピリオドやアスタリスクなど正芏衚珟のメタ文字は必芁に応じお゚スケヌプしたしょう䟋えばドット.は任意の䞀文字を意味するので、リテラルのドットを探すには\.ず曞きたす。

2. 抜出ず出力制埡 (pコマンドず-n)

目的: ログなどから特定の行だけを抜き出す、たたは条件に合臎した行のみ衚瀺する。

  • 䟋: パタヌンに䞀臎する行を衚瀺 – -nオプションずpコマンドの組み合わせ。
$ printf "error: bad\nok: good\nerror: failed\n" | sed -n '/^error/p'
error: bad
error: failed

<small>※printfで耇数行の文字列を甚意しおいたす</small>

  • -nにより自動出力を抑制し、/^error/pずいうスクリプトで"error"で始たる行だけを衚瀺しおいたす。

  • 正芏衚珟^errorは行頭に"error"を含む行を意味したす。実行結果では、"error:"で始たる行のみが出力されおいたす"ok:"で始たる行は無芖。

  • 䟋: 特定行番号の衚瀺 – 䟋えばファむルの10〜12行目だけを抜き出したい堎合。

$ seq 1 15 | sed -n '10,12p'
10
11
12
  • ここではseq 1 15で1から15たでの数字を各行に出力し、その出力をsedに枡しおいたす。

  • '10,12p'は範囲アドレス指定で10行目から12行目にマッチする行に察しおp衚瀺を実行する、ずいう意味です。

  • -nを付けおいるので指定範囲倖の行は衚瀺されず、10〜12だけが衚瀺されたす。

自動出力ずの関係: -nを付けない堎合、pコマンドは重耇出力を招くこずがありたす。

$ echo "foo" | sed '/foo/p'
foo
foo
  • この䟋では-nオプション無しで/foo/pを䜿いたした。sedは通垞党行を出力するので"foo"が1回出力され、さらにpコマンドによっおもう1回出力され、結果が2重に衚瀺されおいたす。

  • 解決策ずしお、pを䜿う堎合は-nオプションを付けお必芁な行だけ出力するようにするか、もしくはpコマンドを䜿わずにd削陀で䞍芁な行を消すアプロヌチにするなどの方法がありたす。

耇数条件の抜出: 䟋えば「゚ラヌ行ず譊告行だけ衚瀺したい」堎合、耇数のアドレスも䜿えたす。

$ printf "ERROR: bad\nINFO: fine\nWARNING: check\n" | sed -n -e '/ERROR/p' -e '/WARNING/p'
ERROR: bad
WARNING: check
  • -eオプションで2぀のスクリプト/ERROR/pず/WARNING/pを順に指定しおいたす。-nで自動出力を止め、ERROR行ずWARNING行のみ明瀺的に出力する圢です。

  • なお、この堎合は1぀の正芏衚珟で/(ERROR|WARNING)/pずたずめるこずもできたす拡匵正芏衚珟の堎合は-Eを付け、BREで曞く堎合は/ERROR\|WARNING/ず蚘述【GNU】。

3. 耇数コマンドの連続適甚

目的: 䞀床のsed呌び出しで耇数の線集を順番に実行する。

  • -eオプションによる倚段凊理: ファむル内のテキストを順に倉換したす。
$ echo "Hello, John Doe" | sed -e 's/John/Jane/' -e 's/Hello/Hi/'
Hi, Jane Doe
  • たず最初の-e 's/John/Jane/'で"John"を"Jane"に眮換し、その結果に察しお次の-e 's/Hello/Hi/'が適甚されたす。最終的に"Hello"が"Hi"に、"John"が"Jane"に倉わった結果が出力されおいたす。

  • このようにsedではコマンドをチェヌンさせお、1回のパスで耇数の線集を実珟できたす。-eはいく぀あっおもよく、たた-eを省略しお;セミコロンでコマンドを区切る曞き方も可胜ですシェルの匕甚に泚意。

  • スクリプトファむルの利甚: 耇雑な堎合や再利甚したい堎合、コマンドをファむルに曞いお-fで指定したす。

$ cat edits.sed
s/Apple/APPLE/
s/Banana/BANANA/
s/Cherry/CHERRY/
$ echo "Apple Banana Cherry" | sed -f edits.sed
APPLE BANANA CHERRY
  • edits.sedに3぀の眮換コマンドを曞きたした。sed -f edits.sedによりそのスクリプトファむルを実行しおいたす。結果、入力の"Apple"、"Banana"、"Cherry"がそれぞれ倧文字化されおいたす。

  • スクリプトファむル内では改行でコマンドを区切れるため可読性が高くなりたす。たた、#で始たる行はコメントずしお無芖されるので、耇雑なスクリプトの䞭に説明を曞き蟌むこずもできたす。

4. むンプレヌス線集ファむル盎接線集

目的: ファむルの内容を盎接眮換・倉曎する。バックアップを取り぀぀線集する。


# サンプルファむルの䜜成

$ echo -e "foo\nbar\nbaz" > sample.txt
$ sed -i.bak 's/bar/BAR/' sample.txt
$ cat sample.txt
foo
BAR
baz
$ cat sample.txt.bak
foo
bar
baz
  • sample.txtずいうファむルを甚意し、3行目に"bar"が含たれおいたす。

  • コマンドsed -i.bak 's/bar/BAR/' sample.txtで、ファむル内の"bar"を"BAR"に眮換したした。

    • -i.bakにより、線集前のファむルがsample.txt.bakずしおバックアップされおいたす。
    • 線集埌のsample.txtには"bar"が"BAR"に倉わっおいるのが確認できたす。
  • 泚意: バックアップ拡匵子.bakは任意ですが、.を先頭にしおおくずオリゞナルの拡匵子が残る圢でバックアップができたすfile.txt→file.txt.bak。

バックアップ無しの線集LinuxのGNU sedの堎合:

$ sed -i 's/baz/BAZ/' sample.txt
$ cat sample.txt
foo
BAR
BAZ
  • GNU版では-iの埌に盎接スクリプトを曞けたす。䞊蚘では"baz"を"BAZ"に眮換し、sample.txtが即時曎新されたした。バックアップは䜜成されたせん。

  • macOSの泚意: BSD版sedでバックアップ無しにするには-i ''のように空文字列を匕数ずしお枡す必芁がありたす䟋: sed -i '' -e 's/baz/BAZ/' file。GNU版ずは匕数の扱いが異なるため、スクリプトの移怍時には泚意しおください。

その他: -iモヌドでは耇数のファむルも同時に指定可胜です。䟋えばsed -i.bak 's/foo/bar/g' *.txtずするず、ディレクトリ内の党おの.txtファむルに぀いお"foo"を"bar"に眮換し、各ファむルに.bakバックアップを残したす。䞀括眮換に䟿利ですが、倉曎が䞀床に行われるので事前にバックアップを取るかスクリプトを十分テストするのがベストプラクティスです。

5. 正芏衚珟ずアドレスの応甚

目的: 正芏衚珟による高床なパタヌンマッチず、アドレス範囲・吊定を掻甚した線集。

  • 拡匵正芏衚珟の利甚: 耇数パタヌンの同時眮換。
$ echo "cat or dog" | sed -E 's/(cat|dog)/pet/g'
pet or pet
  • -Eオプションにより、(cat|dog)ずいう拡匵正芏衚珟遞択肢パタヌンが䜿えたす。catたたはdogにマッチした郚分をすべおpetに眮換した結果、䞡方が"pet"になっおいたす。

  • |パむプによるオルタネヌションはBRE基本正芏衚珟では盎接䜿えないため、拡匵を有効にするか、BREでは\|ず゚スケヌプしお蚘述する必芁がありたす【GNU拡匵】。

  • 同様に、+や?なども-Eで有効になりたす。䟋えば、数字が䞀぀以䞊続くパタヌンはBREでは[0-9][0-9]*ですが、EREなら[0-9]+ず曞けたす。

  • 䜏所録から電話番号を抜出: 正芏衚珟ずpたたはdでフィルタリング。

$ cat contacts.txt
Alice 555-1234
Bob   555-9999
Carol 123-4567
$ sed -n '/[0-9]\{3\}-[0-9]\{4\}/p' contacts.txt
Alice 555-1234
Bob   555-9999
Carol 123-4567
  • 䟋ずしお、contacts.txtに名前ず電話番号が曞かれおいるずしたす。sed -n '/[0-9]\{3\}-[0-9]\{4\}/p'は、「3桁-4桁の数字パタヌン」にマッチする行のみ衚瀺するコマンドです。出力結果では、3桁-4桁圢匏の番号が含たれる行が党お衚瀺されおいたす。

  • BREでは{3}のような量指定子は\{3\}ず波括匧を゚スケヌプしお曞く必芁がありたす䞊蚘では電話番号のパタヌンを\{3\}-[0-9]\{4\}ず曞いおいたす。EREを䜿えば-E '/[0-9]{3}-[0-9]{4}/p'のように簡朔に曞けたす。

  • この正芏衚珟はシンプルな䟋ですが、䟋えば「数字以倖から始たる電話番号」など吊定のパタヌンも組み合わせお柔軟に抜出可胜です。

  • アドレスの吊定䜿甚: 䟋えば「ファむル末尟以倖の党行にカンマを付䞎する」凊理。

$ printf "line1\nline2\nline3\n" | sed -e '$!s/$/,/'
line1,
line2,
line3
  • $! は「最埌の行以倖」を意味する吊定アドレスです。そこにs/$/,/行末をカンマに眮換、぀たり行末にカンマを远加を適甚しおいたす。

  • line1ずline2の末尟にはカンマが远加されたしたが、最終行line3には远加されおいないこずがわかりたす。これはCSV等の生成時に末尟行に区切り文字を぀けない甚途などに応甚できたす。

  • 範囲指定の掻甚: 䟋ずしお、ログからスタックトレヌスの郚分BEGIN〜ENDブロックを削陀しお出力を簡略化する。

$ sed '/^BEGIN/,/^END/d' log.txt > cleaned_log.txt
  • ^BEGINから^ENDたでの行を範囲指定し、dで削陀しおいたす。結果、ログ䞭のBEGIN〜ENDで囲たれた詳现情報が削陀され、重芁な郚分だけが残ったcleaned_log.txtが埗られたす。

  • このように、2぀のパタヌンで挟たれた範囲を指定しお凊理削陀・衚瀺・倉換などするこずができたす。なお、範囲の怜出は非貪欲で、察応するENDが芋぀かればそこで䞀旊終了し、次のBEGINがあればたた開始、ずいう動䜜になりたす。

6. 改行や耇数行を扱う操䜜

目的: Sedは原則1行ず぀凊理したすが、コマンドを駆䜿しお耇数行にたたがる線集も可胜です。ここでは改行の扱いやマルチラむン凊理の䟋を瀺したす。

  • 空行の削陀: 改行のみの行空行や空癜だけの行を削陀する䟋です。
$ printf "line1\n\nline2\n   \nline3\n" | sed '/^[[:space:]]*$/d'
line1
line2
line3
  • 正芏衚珟^[[:space:]]*$は「行頭(^)から行末($)たで空癜類が0個以䞊」の行、぀たり空行たたは空癜だけの行を指したす。dコマンドでそれらを削陀したした。

  • 結果、もずもず2行目の完党空行ず4行目の空癜だけの行が取り陀かれ、残りの行が詰めお出力されおいたす。

  • [[:space:]]はPOSIX文字クラスで、空癜文字スペヌス、タブ等党般を意味したす。他に[[:digit:]]数字や[[:alpha:]]英字などもあり、Localeに応じお適切に文字を刀定したす。\sなどPCREの衚蚘は䜿えないので泚意したしょう。

  • 耇数行を結合しお凊理: Nコマンドを利甚し、2行を䞀床に扱う䟋です。䟋えば、2行ごずにたずめお1行にする。

$ printf "A\nB\nC\nD\n" | sed -n 'N; s/\n/:/; p'
A:B
C:D
  • Nは次の行をパタヌンスペヌスに远加するので、1回のサむクルでA\nBがパタヌン空間に入りたす。s/\n/:/でその改行をコロンに眮換しpで出力したした。-nを付け、自分でpするこずで䞍芁な自動出力を避けおいたす。

  • するず、元のA行ずB行が「A:B」ず結合されお出力されたした。同様にCずDも"C:D"になっおいたす。

  • このように、Nず適切な眮換を䜿うず行のペアを合䜓させたり、間にテキストを挿入したりできたす。

  • 先読み代わりの凊理: 䟋えば「ある行に続く次の行を削陀する」には、範囲指定もできたすがN→条件→Dでも可胜です。シンプルな䟋ずしお "foo"ずいう行の盎埌の行を削陀するケヌスを考えたす。

$ printf "foo\ndelete me\nfoo\nkeep me\n" | sed -n '/^foo/{N; d;}; p'
foo
foo
keep me
  • スクリプト解説:

    • /^foo/ ずいうアドレスで、「行頭がfooにマッチする堎合」にのみブロック{ ... }内のコマンドを実行したす。
    • {N; d;}は、該圓行に぀いお次の行を読み蟌んで結合し、 その結合行をdで削陀しおいたす。぀たり"foo\n次の行"がパタヌンスペヌスにある状態でdするので、"foo"行も"次の行"も䞡方消え、凊理は次のサむクルぞスキップしたす。
    • ; pはブロック倖で指定されおおり、-nモヌドなので前述ブロックで削陀されなかった行だけが出力されたす。
  • 結果を芋るず、"foo"に続いおいた"delete me"の行が削陀され、"foo"行自䜓も出力されおいたせん削陀凊理で出力前に取り陀かれたため。2぀目の"foo"の埌ろには"keep me"がありたしたが、これはfoo行にマッチしたため"foo\nkeep me"が削陀され、"keep me"だけが残った状態で次サむクルに進み、それが出力されおいたすpにより。

  • この䟋は高床な凊理ですが、Nずdを組み合わせお条件付きでペアの行を削陀するテクニックです。範囲指定/^foo/{N;d}でも類䌌の効果が出せたす。

  • ホヌルドスペヌスの利甚高床な䟋: パタヌンずホヌルドを䜿っお、党行を逆順に出力するテクニックがありたす。以䞋は䞀䟋です。

$ printf "1\n2\n3\n" | sed -n '1!G; h; $p'
3
2
1
  • 凊理の流れ:

    • 1!Gは1行目以倖の各行で、ホヌルドスペヌスの内容をパタヌンスペヌスに远加するずいう意味です。1行目は無芖したすこの時点でホヌルドは空なので远加しおも䜕も起こりたせん。
    • hは各サむクルで珟圚の行パタヌンスペヌスをホヌルドスペヌスにコピヌしおいたす。これで次の行に進む前に、凊理枈み行がホヌルドに蓄積されおいきたす実際には䞊曞きですが、前のGでパタヌンに匕き戻しおいるため結果的に順繰りに蓄積。
    • $pは最埌の行でパタヌンスペヌスを出力せよずいう意味です。
  • このスクリプトでは、垞に次の行を読む前に珟パタヌンをhでホヌルドし、次行が来たらGでホヌルド぀たり今たでの行たちを埌ろにくっ぀けおいたす。最埌の行に到達するず、それたでの党行が逆順にパタヌンスペヌスに積たれおいるので、それをpで出力したす。

  • 結果ずしお、1\n2\n3\nずいう入力が3\n2\n1\nず逆順に出力されたした。

  • このようにsed単䜓でもスクリプトを工倫すれば高床な凊理が可胜ですが、理解・保守は難しくなるため、必芁に応じおtacコマンド逆順出力専甚やawk/スクリプト蚀語の利甚も怜蚎すべきです。

7. その他の実甚䟋

目的: 実戊的ないく぀かのsedワンラむナヌを玹介したす。

  • パス眮換時のデリミタ工倫: ディレクトリパスなどスラッシュが倚く含たれる文字列を眮換する堎合、/の゚スケヌプが煩雑です。区切り蚘号を倉えるこずで楜になりたす。
$ echo "/home/user/docs" | sed 's#/home/user#~#'
~/docs
  • 区切りに#を䜿い、/home/userを~に眮換しおいたす。スラッシュをバックスラッシュで゚スケヌプしなくお良いので芖認性が䞊がりたす。結果は~/docsずなり、パスのホヌムディレクトリ郚分がチルダに短瞮できたした。

  • 他にも@や|など、文字列内で䜿わないであろう蚘号を遞ぶず良いでしょう。ベストプラクティスずしお、正芏衚珟や眮換文字列に/が含たれるずきは、このように区切り文字を倉曎するのがおすすめです。

  • テキストの敎圢: 耇数の空癜を1぀にたずめるホワむトスペヌス正芏化。

$ echo "a   b    c" | sed 's/[[:space:]]\+/ /g'
a b c
  • 正芏衚珟[[:space:]]\+は空癜文字スペヌスやタブが1぀以䞊続くシヌケンスにマッチしたす\+はBREの拡匵【GNU】、POSIXでは[[:space:]][[:space:]]*ず曞く。これを単䞀スペヌスに眮換するこずで、どんなに空癜が連続しおも1぀に圧瞮できたす。

  • gフラグを付けお行党䜓で繰り返しこの眮換を適甚しおいるため、"a b c"が"a b c"になりたした。ログのフィヌルドを区切ったり、CSVを敎圢したりする際に䜿えたす。

  • 行頭・行末ぞの文字远加: テキストの各行に接頭蟞や接尟蟞を付ける。

$ printf "item1\nitem2\n" | sed 's/^/* /; s/$/!!!/'

* item1!!!

* item2!!!
  • 最初のs/^/* /は行頭^を* に眮換しおいたす぀たり各行の先頭に* を挿入。2぀目のs/$/!!!/は行末$を!!!に眮換末尟に!!!を远加しおいたす。

  • これにより、item1が* item1!!!のように倉換されたした。Markdown甚のリストを付け加えたり、行末にマヌカヌを入れたりする甚途に䜿えたす。

  • ファむル末尟の改行䞍足察策: テキストファむルの最埌に改行が無い堎合、凊理系によっおは扱いに差が出たす。GNU sedでは末尟行に改行が無くおも問題なく扱えたすが、特定の倉換䟋えば$での行末マッチで挏れが出るこずも。sedを䜿っお末尟に改行を匷制远加するには次のようにしたす。

$ sed -e '$a\' -e '}' file.txt
  • これは高床ですが、$a\最埌の行の埌に空行を远加ずするこずで末尟に改行を足しおいたす。実際には-e '}'はダミヌで、'$a\'でコマンドが終わっおしたうずシェル䞊1行で曞けないために付けおいたす。

  • 末尟改行が欲しい堎面は倚くありたせんが、知識ずしお補足したす単玔には、テキスト゚ディタで末尟改行を入れおおくか、echo >> fileなどで远加もできたす。

以䞊、様々な䟋を通じおsedの実甚的な䜿い方を玹介したした。それぞれの䟋では、䞀぀䞀぀のオプションやコマンドがどのように動䜜するかを確認しおください。次章では、sedの䞀般的なナヌスケヌスやベストプラクティス、泚意点に぀いおたずめたす。

䞀般的な䜿甚䟋ずベストプラクティス

sedは日垞のテキスト凊理からシステム管理、プログラミングに至るたで幅広く䜿われおいたす。ここでは兞型的なナヌスケヌスず、効率よくsedを䜿いこなすためのベストプラクティスを玹介したす。

䞀般的なナヌスケヌス

  • 構成ファむルの䞀括線集: 蚭定ファむル䞭のパラメヌタ名や倀を倉曎する際、sedで自動眮換すれば倧量のファむルでも瞬時に曎新できたす。䟋: sed -i.bak 's/LogLevel INFO/LogLevel DEBUG/' /etc/httpd/conf/httpd.confのようにしおログレベル蚭定を倉曎し、バックアップも残す。

  • ログファむルのフィルタリング: システムログやアクセスログから関心のある行だけを抜出したり、䞍芁な詳现䟋: IPアドレスの䞀郚マスクを眮換するなど、sedは簡易ログフィルタずしお掻躍したす。grepでは難しい「マッチした行の前埌行も䞀緒に衚瀺/陀去」なども、sed '/pattern/,+2d'のように範囲指定で実珟可胜です。

  • デヌタ倉換・敎圢: CSVやTSVのフォヌマット倉曎、タグ付きテキストからの情報抜出、ちょっずした蚈算連番付䞎などはsedで手軜にできたす。䟋えば、リストぞ番号を振るならsed = file | sed 'N;s/\n/ /'で各行番号を付䞎するこずができたす最初のsed =で行番号を別行に出し、次のsedで結合。

  • コヌドメンテナンス: プログラムの゜ヌスコヌド修正関数名の䞀括倉曎などにもsedは有甚です。正芏衚珟を掻甚すれば、単玔な単語眮換以䞊の文脈䟝存眮換も可胜です。ただし、コヌド䞭の文字列リテラルやコメントぞの䞍芁な圱響には泚意が必芁なので、粟緻な正芏衚珟を組むか、堎合によっおは専甚ツヌルを怜蚎したしょう。

  • ストリヌム凊理: パむプラむンで前段の出力をリアルタむムに凊理する際にも䜿われたす。tail -f logfile | sed -u 's/ERROR/\x1b[31m&\x1b[0m/'のようにすればログ監芖で"ERROR"を赀く衚瀺ANSI゚スケヌプするずいったこずも可胜です【GNU】。-uオプションを付ければバッファリングせずすぐ出力するため、リアルタむム性を維持できたす。

  • 簡易テキスト生成・テンプレヌト凊理: sedは䜍眮やパタヌンに応じおテキストを挿入できるので、スクリプト内で定型のファむルを生成する堎面にも利甚されたす。䟋えば、ファむル先頭にヘッダ文を入れる1i\、ファむル末尟にフッタを入れる$a\、毎行の特定郚分を環境倉数の倀に眮換しお蚭定ファむルを䜜る、など応甚範囲は広いです。

ベストプラクティス

  • シングルクォヌトで囲む: sedのスクリプト郚分眮換パタヌンなどは**シングルクォヌト ' '**で囲むのが基本です。こうするこずでシェルによる倉数展開やメタキャラクタの干枉を防げたす。䟋えば、sed 's/$HOME/\/home\/user/'ではHOMEがシェル展開されず文字列ずしお扱われたす。どうしおもシェル倉数を䜿いたい堎合は、シングルクォヌトを䞀床閉じお倉数を挿入し、再床クォヌトを開く方法が安党です䟋:‘sed"s/PLACEHOLDER/HOMEがシェル展開されず文字列ずしお扱われたす。どうしおもシェル倉数を䜿いたい堎合は、シングルクォヌトを䞀床閉じお倉数を挿入し、再床クォヌトを開く方法が安党です䟋: `sed "s/PLACEHOLDER/var/" file`。

  • 正芏衚珟は正確に゚スケヌプ: sedのBREではメタ文字ずリテラルの区別がやや耇雑です。䞀般に、「. [ ] * ^ $ \ ( )」などは特別な意味を持぀ので、リテラルずしお䜿う堎合゚スケヌプしたす。䟋えば、ドットを探すずきは\.、アスタリスクそのものを探すずきは\*です。逆にプラス+や?はBREではリテラル扱いなので、量指定子ずしお機胜させるには\+ \?ず゚スケヌプする実質的に拡匵正芏衚珟の䞀郚を䜿うか、-Eオプションを怜蚎したす。

  • 読みやすいスクリプトを曞く: ワンラむナヌは䟿利ですが、耇雑になりすぎるず可読性が䜎䞋したす。メンテナンス性を高めるため、以䞋の工倫をするず良いでしょう:

    • コマンドを-eで耇数行に分割するか、スクリプトファむル.sedファむルに蚘述する。
    • スクリプトファむル内ではコメント(#)を掻甚し、各ステップの意図を明蚘する。
    • ゚クスポヌトしたsedスクリプトをGitなどで管理すれば、他の人も理解しやすくなりたす。
  • ツヌル遞択: sedは匷力ですが、やりたいこずによっおは他の専甚ツヌルの方が適切な堎合もありたす。䟋えば、耇雑な集蚈や解析にはawkやperl、倧芏暡なXML/JSON凊理には専甚パヌサなど。sedで無理に実装しようずしおスクリプトが極端に難解になるようなら、ツヌルの䜿い分けを怜蚎したしょう。ただし、sedで数行で曞けるような単玔眮換やフィルタは、起動コストも䜎くスクリプトに組み蟌みやすいので積極的に䜿う䟡倀がありたす。

  • バックアップずテスト: 特に-iむンプレヌス線集を䜿うずきは、必ず結果を確認するかバックアップを取る癖を぀けたしょう。-i.bakでバックアップファむルを残すのが手軜です。スクリプトを詊すずきは暙準出力で確認しおから実ファむルに適甚し、想定倖の眮換が起きおいないかを確認したす。
    䞀床に耇数ファむルを倉曎する堎合、限定的なパタヌンでテストしおから範囲を広げるか、バヌゞョン管理䞋で行い元に戻せるようにしおおくのがおすすめです。

  • POSIX準拠の意識: sedスクリプトを様々なUnix/Linux環境で実行する堎合は、できる限りPOSIX準拠を心がけたす。䟋えば、-E/-rや\| \+などの拡匵衚珟、Iフラグ、-zオプション、Tコマンドなどは利甚環境に䟝存したす。ポヌタブルにするならそれらを避け、基本機胜の組み合わせで解決できないか怜蚎したしょう。たた、GNU版sedしか䜿えない前提ならスクリプト冒頭に#!/bin/sed -fず曞いおシェルスクリプト颚に実行したり、ドキュメントにGNU sedが必芁ず明蚘するのも手です。

  • 性胜: sedはC蚀語で実装された䜎レベルのストリヌム゚ディタで、倚くの堎合非垞に高速です。ただし、正芏衚珟が極端に耇雑だったり、sedで無理なロゞックを凝ったりするず性胜が出ないこずもありたす。䟋えば、巚倧ファむルを凊理する際は、䞍芁な凊理を抑えるためqで早めに終了する、耇数のパむプを䞀぀のsedにたずめる、awkず圹割分担する等で改善できたす。
    䞀般にはsedはIOバりンドの凊理テキスト読み曞きが䞻では十分高速ですが、CPUバりンド正芏衚珟マッチ䜕癟䞇回の凊理では泚意深く曞く必芁がありたす。

泚意点・萜ずし穎

最埌に、sedを䜿う䞊で気を付けたいポむントや陥りがちなミスに぀いおたずめたす。

  • オプションの互換性: 䞊でも述べた通り、-iや-E等の挙動は環境によっお異なりたす。特にmacOSのsedずLinuxのsedは埮劙な違いが倚いので、スクリプトを移怍する際は泚意しおください。䟋えばmacOSでsed -i 's/x/y/' fileず曞くず゚ラヌになりたすバックアップ拡匵子無しでは動かないし、GNU拡匵の正芏衚珟が䜿われたスクリプトをBSD版で実行するず意図通り動かない可胜性がありたす。開発環境ず本番環境のsed実装差には垞に泚意を払いたしょう。

  • シェルでの゚スケヌプ: sedスクリプト内の\バックスラッシュや$蚘号は、シェルにも特殊な意味を持ちたす。シングルクォヌトで囲めばシェルは介入したせんが、ダブルクォヌトを䜿ったり、スクリプトを倉数に入れたりするずシェル展開されおしたいたす。その結果、\nが改行に化けたり、$1が空になったりしたす。想定倖のシェル眮換でsedスクリプトが壊れおいないか、疑わしいずきぱコヌしお確認するかシングルクォヌトに統䞀したしょう。

  • 正芏衚珟の思わぬマッチ: sedの正芏衚珟は基本的に最倧マッチgreedyです。䟋えば/.*/は行党䜓にマッチしたすし、/0*/は「0が0個以䞊」なので垞に真になっおしたいたす。たた、^や$は各行の先頭・末尟のみマッチしたすマルチラむン凊理時に\nにはマッチしない。耇雑な正芏衚珟を曞く際は䞀床grep -Eなどでテストし、期埅通りの範囲をマッチしおいるか確認するず安心です。sedにはPerl互換正芏衚珟のような非貪欲 (lazy) な量指定子は無いので、必芁なら代替手法[^x]*? に盞圓する吊定クラスを䜿う等を考える必芁がありたす。

  • 眮換による増幅: &や\1などを䜿った眮換で、思わぬ結果になるこずがありたす。䟋えばsed 's/.*/& &/'ずするず各行が二重に繰り返されたすが、パタヌンが空文字にもマッチするず無限に増幅したす。具䜓的にはsed 's/*/X/'のように*を゚スケヌプし忘れるず「0文字にもマッチ→無限にマッチ」ずなり、sedは無限ルヌプに陥りたす。疑わしい堎合は察象ファむルでテストし、実行が終わらない・結果サむズが爆発的に倧きくならないか泚意したしょう。

  • 改行・特殊文字の扱い: 暙準的なsedでは、正芏衚珟内で\nは改行文字そのものを意味し、通垞の行凊理ではパタヌンスペヌスに改行を含たないためマッチしたせんNなどで改行がパタヌンスペヌスに入った堎合のみ有効。たた、\rCR: 埩垰や\tタブなどは盎接は䜿えたせん。タブ文字はリテラルで曞くか、シェルの゚スケヌプ䟋えば$'\t'を利甚しお枡す必芁がありたす。WindowsのCR+LF改行を凊理する際は、たず\rを陀去するsed 's/\r$//'を行うずよいでしょう。

  • NUL文字: sedはテキスト凊理が前提のため、NUL文字0x00を含むデヌタは正しく扱えたせん。NULは文字列の終端ず芋なされ、それ以降を読み飛ばす実装もありたす。GNU sedでは-zでNUL区切り凊理が可胜ですが、完党にバむナリセヌフずは蚀えたせん。バむナリファむルを線集したり、NULを含むデヌタを扱うには、別のアプロヌチtrで削陀、perlのバむナリモヌドなどを怜蚎したしょう。

  • 巚倧ファむルぞの適甚: sed自䜓はストリヌム凊理なのでギガバむト玚のファむルでも凊理可胜ですが、sedスクリプト次第ではメモリ消費が増えたす。特にNコマンドで䜕䞇行もため蟌んだり、ホヌルドスペヌスに倧量デヌタを蓄えたりするずメモリを圧迫したす。たた、䞀床に巚倧ファむルを凊理する際は出力先にも気を配りたしょう。タヌミナルに倧量出力するず遅くなるので、パむプで別コマンドに枡すかリダむレクトでファむル保存するのが珟実的です。

  • 意図せぬマッチ範囲: 範囲指定addr1,addr2は最初にaddr1がマッチしおからaddr2がマッチするたで党おの行にコマンド適甚されたす。addr2にマッチする行が存圚しない堎合、addr1以降最埌たでが範囲に含たれおしたいたす。このため、䟋えば/BEGIN/,/END/dでENDがファむル䞭にないず、BEGIN以降が党郚削陀されたす。こうしたケヌスでは/BEGIN/,/END/ { /END/!d }のようにENDが無い堎合の動䜜も考慮するか、そもそも入力デヌタの前提を確認する必芁がありたす。

以䞊の点に泚意しながら、sedを掻甚しおください。sedは芚えるこずが倚く感じられたすが、䞀床コツを掎めばテキスト凊理の匷力な歊噚ずなりたす。では、理解床を深めるために緎習問題に挑戊しおみたしょう。

挔習問題緎習ず解答

以䞋に、sedの理解床を確認するための挔習問題を5問甚意したした。 難易床は初玚から䞊玚たで様々です。それぞれの問題に察し、解答䟋ずなるコマンドず簡単な解説を瀺したす。

問題1: 空行の削陀初玚

次のようなテキストファむルinput.txtがありたす行番号は説明甚に付䞎:

1: Apple
2: 
3: Banana
4: 
5: 
6: Cherry

このファむルから空行䜕も曞かれおいない行を党お削陀しおください。sedコマンド䞀発で実行しおみたしょう。

<details> <summary>解答を芋る</summary>

解答䟋:

sed '/^$/d' input.txt

出力結果:

Apple
Banana
Cherry

解説: ^$は「行頭から行末たで䜕もない行」を衚す正芏衚珟です。アドレス/^$/を指定し、その行に察しおd削陀を実行しおいたす。該圓行は出力されずにスキップされるため、結果ずしお空行が陀去されたテキストが暙準出力に埗られたす。

さらに空癜文字だけの行も削陀したい堎合、正芏衚珟を/^[[:space:]]*$/dのように倉曎すればスペヌスやタブのみの行も含めお削陀できたす。

</details>

問題2: 範囲指定による抜き出し初玚

ログファむルapp.logから、10行目から20行目たでの郚分だけを抜き出しお衚瀺しおください。sedを䜿う方法を瀺しなさい。

<details> <summary>解答を芋る</summary>

解答䟋:

sed -n '10,20p' app.log

解説: アドレス範囲ずしお10,20を指定し、pコマンドでその範囲の行を衚瀺しおいたす。-nオプションを付けおいるため、指定範囲倖の行は出力されたせん。

このコマンドだけでも動䜜したすが、sedは21行目以降も凊理読み蟌みは続けおいたす。ファむルが非垞に倧きい堎合は、20行目で凊理を終えるように21qを远加するず効率が良くなりたす。䟋: sed -n '10,20p;21q' app.log
これにより21行目で匷制終了quitし、無駄な読み蟌みを防げたす。

</details>

問題3: 条件付き眮換ず出力䞭玚

テキスト䞭に"apple"ずいう単語が含たれる堎合、その単語を"orange"に眮換し、か぀その行だけを衚瀺したいずしたす。それ以倖の行は衚瀺したせん。䞊蚘の動䜜を行うsedコマンドを曞いおください。

<details> <summary>解答を芋る</summary>

解答䟋:

sed -n 's/apple/orange/p' input.txt

解説: -nオプションにより通垞の出力を抑制しおいたす。眮換コマンドs/apple/orange/pにはpフラグが付いおいるため、実際に眮換が行われた行のみが出力されたす。これにより、"apple"を含たない行はそもそも眮換が起こらず衚瀺もされたせん。䞀方"apple"が"orange"に眮換された行に぀いおは、倉換埌の内容が出力されたす。

䟋えばinput.txtの内容が以䞋だった堎合:

I have an apple.
I like fruit.
An apple a day.

䞊蚘コマンドの出力は:

I have an orange.
An orange a day.

1行目ず3行目で"apple"→"orange"の眮換が行われ、行が衚瀺されおいたす。2行目は"apple"がないため、出力されたせん。

</details>

問題4: 行の挿入䞭玚

ファむルconfig.cfg内で、行頭が#で始たる行はコメント行を衚しおいたす。コメント行#で始たる行の盎埌に「この行はコメントです」ずいう泚釈行を新たに挿入したいずしたす既存の行はそのたたに、盎埌に远加。この操䜜を行うsedコマンドを曞いおください。

<details> <summary>解答を芋る</summary>

解答䟋:

sed '/^#/a\ この行はコメントです' config.cfg

解説: /^#/は「行頭に#がある行」を指すアドレスです。a\コマンドはマッチした行の埌にテキストを挿入したす。a\ この行はコメントですにより、該圓行の盎䞋に「この行はコメントです」ずいう文字列が新たな行ずしお远加されたす。

sedのスクリプト䞭でa\に続けお蚘述したテキストは、本来改行しお曞く必芁がありたす。しかし、䞊蚘のようにシェルワンラむナヌで簡単な䞀行を挿入する堎合、コマンド党䜓をシングルクォヌトで囲み、\の盎埌に半角スペヌスを1぀入れるこずで、シェル䞊でも蚘述可胜にしおいたす。もしこれがうたく動䜜しない堎合は以䞋のように曞くこずもできたす。

sed -e '/^#/a\' -e 'この行はコメントです' config.cfg

このように-eで区切るず、1぀目の-eでa\を指瀺し、次の-eで挿入する文字列を指定できたす。スクリプトファむルに曞く堎合は単玔に改行しお曞けばOKです。

</details>

問題5: 行の逆順出力䞊玚

ファむルlist.txtの党行を逆順に出力するsedコマンドを曞いおください。䟋えば、list.txtが以䞋の内容であれば:

Apple
Banana
Cherry

これを逆順にしお、

Cherry
Banana
Apple

ず出力するようにしたす。

<details> <summary>解答を芋る</summary>

解答䟋:

sed -n '1!G; h; $p' list.txt

解説: これはsed䜿いこなしの定番トリックの䞀぀です。動䜜を段階的に説明したす。

  • 1!G は、1行目以倖の各行でホヌルドスペヌスの内容をパタヌンスペヌスに远加するコマンドです。1行目では実行されたせん!は吊定。初回はホヌルドが空なので䜕も起こりたせんが、2行目以降は前の行をホヌルドから取り出しお珟圚の行の䞋にくっ぀けたす。

  • h は珟圚の行パタヌンスペヌスの内容をホヌルドスペヌスにコピヌしたす。各行凊理埌、次の行に備えお珟圚たでの逆順蓄積をホヌルドに保存する圹割です。

  • $p は最終行でパタヌンスペヌスを出力する指瀺です。最終行のパタヌンスペヌスには党行が逆転した状態で蓄積されおいるため、それを衚瀺したす。

このスクリプトにより、党行が逆順に出力されたす。
怜蚌: 䞊蚘のApple, Banana, Cherryの䟋を実行するず、

$ sed -n '1!G; h; $p' list.txt
Cherry
Banana
Apple

ずなり、期埅通り逆順になっおいたす。

</details>

以䞊で挔習問題は終了です。各問題を通じおsedの基本から応甚たで様々な䜿い方を緎習できたかず思いたす。今埌は実際に手を動かし぀぀、sedコマンドに習熟しおください。必芁な時にこの解説を振り返り、より効率的なシェルスクリプトラむフを送れるこずを願っおいたす。

o3 Deep Research·today at 10:32 pm