sed

sed
パラダイムスクリプト
デザイン:リー・E・マクマホン
初登場1974 (1974年
実装言語C
影響を受けた
ed
影響を受けた
PerlAWK

sed (ストリーム エディタの略)、比較的単純でコンパクトなプログラミング言語で書かれたスクリプトによってテキストを変換するユーティリティです。1973 年から 1974 年にかけてベル研究所Lee E. McMahonによって開発され、[ 1 ] 現在ではほとんどのオペレーティング システムで利用できます。[ 2 ] sed の機能は、対話型エディタed (「エディタ」、1971 年) とそれ以前のqed (「クイック エディタ」、1965 ~ 1966 年) のスクリプト機能に基づいています。sed は正規表現をサポートする最も初期のツールの 1 つであり、置換コマンドなどにより、現在でもテキスト処理に使用されています。テキスト操作やストリーム編集用の一般的な代替ツールとしては、 AWKPerl などがあります。このユーティリティを実行するシェルコマンドの名前も同じです。 sed

歴史

バージョン 7 Unixで初めて登場した[ 3 ] sed は、データ ファイルのコマンド ライン処理用に構築された初期の Unix ユーティリティの 1 つです。人気のgrepコマンドの自然な後継として進化しました。[ 4 ]元々の動機は、置換に対する grep (g/re/p) の類似物であったため、「g/re/s」となりました。[ 3 ]各コマンドに対して、g/re/d などの専用プログラムも登場することを予見して、McMahon は汎用の行指向ストリーム エディタを作成し、これが sed になりました。[ 4 ] sed の構文、特にパターン マッチングの と置換の使用は/当時一般s///的に使用されていた sed の前身であるedに由来します[ 4 ]また、正規表現の構文は他の言語、特にECMAScriptPerlに影響を与えています。その後、より強力な言語であるAWKが開発され、これらは従兄弟のように機能し、シェル スクリプトで強力なテキスト処理を実行できるようになりました。sed と AWK は、Perl の先駆者およびインスピレーションとしてよく挙げられ、特に一致演算子と置換演算子において、Perl の構文とセマンティクスに影響を与えました。

GNU sed には、ファイルのインプレース編集など、いくつかの新機能が追加されました。 Super-sedは sed の拡張バージョンで、 Perlと互換性のある正規表現が含まれています。 sed の別の亜種であるminisedは、もともとEric S. Raymondによって 4.1BSD sed からリバースエンジニアリングされ、現在はRené Rebeによってメンテナンスされています。 minised は、GNU プロジェクトが新しい GNU 正規表現ライブラリに基づいて sed の新しいバージョンを作成するまで、GNU プロジェクトによって使用されていました現在の minised には BSD sed の拡張機能がいくつか含まれていますが、 GNU sed ほど機能が豊富ではありません。その利点は非常に高速でメモリをほとんど使用しないことです。これは組み込みシステムで使用され、 Minixで提供される sed のバージョンです。[ 5 ]

処理

sed は、入力ストリーム(ファイルなど)から 1 行ずつテキストを読み取り、パターン スペースと呼ばれる内部バッファーに格納します。スクリプトで指定されているとおり、sed はコマンド ( sed のドキュメントではアクションと呼びます) をパターン スペースに適用します。特に指示がない限り、sed はパターン スペース (変更された行) を出力し、次の行からサイクルを再開します。その他のスクリプト終了時の動作は、コマンドライン オプションやスクリプト コマンドで実行できます。たとえば、dパターン スペースを削除する、q終了する、N次の行を直ちにパターン スペースに追加する、などです。つまり、sed スクリプトは、ストリームの各行を反復処理するループの本体に相当し、ループ自体とループ変数 (現在の行番号) は暗黙的に定義され、sed によって管理されます。

入力行、変数(パターンスペースとホールドスペース)、入出力ストリーム、そしてデフォルトのアクション(パターンスペースへの行のコピー、パターンスペースの印刷)に対する反復処理は暗黙的に実行されるため、簡潔なワンライナープログラムを書くことができます。例えば、このスクリプトは10q入力の最初の10行を印刷し、その後停止します。

使用

条件付き実行

コマンドは、オプションのアドレス引数として行番号または正規表現を受け取ります。アドレスはコマンドが適用されるタイミングを決定します。例えば、は2番目の入力行に対して (delete) コマンド2dを実行し、はスペースで始まるすべての行を削除します。一部のコマンドでは、サイクル間でテキストを保持・蓄積するために、別の特別なバッファであるhold space を使用します。この言語は2つの変数(「hold space」と「pattern space」)とGOTOのような分岐機能のみを提供しますが、チューリング完全であり[ 6 ] [ 7 ]倉庫アルカノイド[ 8 ]チェス[ 9 ]テトリスなどのゲーム用の難解なsedスクリプトも存在します。[ 10 ]d/^ /d

マッチング

sedは、入力テキストをパターンに一致させるための正規表現構文をサポートしています。例えば、このスクリプトではd'/^ *$/d'コマンドを使用して、スペースのみを含む行や改行文字のみを含む行を除外しています。

サポートされている正規表現メタ文字は次のとおりです。

キャレット^
行の先頭に一致します。
ドル記号$
行の末尾に一致します。
アスタリスク*
前の文字の 0 回以上の出現と一致します。
プラス+
前の文字の 1 回以上の出現と一致します。
疑問符?
前の文字の 0 回または 1 回の出現と一致します。
ドット.
正確に 1 つの文字と一致します。

代替

sedの元々の目的は置換でした。[ 4 ]次のコマンドラインは置換コマンドを使用しています。

sed 's/regexp/replacement/g'入力ファイル名>出力ファイル名 

は置換を表しs、 はgグローバルを表します。これは、行内の一致するすべての出現箇所が置換されることを意味します。検索対象の正規表現パターンは最初の区切り記号(ここではスラッシュ)の後に配置され、置換対象は2番目の記号の後に配置されます。スラッシュ(/)はedの「検索」を表す文字に由来する慣例的な記号ですが、パターンや置換に含まれていない場合は、構文を読みやすくするために他の記号を使用することもできます。これは「つまようじの傾き症候群」を回避するのに役立ちます。

ed の検索置換機能に由来する置換コマンドは、単純な解析とテンプレート化を実装しています。 はregexpパターンマッチングと部分式によるテキストの保存の両方を提供します。 はreplacementリテラルテキスト、または「完全一致」を表す文字を含む書式文字列、あるいはn番目に保存される部分式を表す&特殊エスケープシーケンスの いずれかです。例えば、 は「cat」または「dog」をすべて「cats」または「dogs」に置き換えますが、既存の「s」は重複しません。は正規表現内の最初の(そして唯一の)保存された部分式であり、 は書式文字列内でこれを出力に置き換えます。 \1\9sed -r "s/(cat|dog)s?/\1s/g"(cat|dog)\1

制御フロー

制御フローは、ラベル(コロンに続く文字列)と分岐命令bまたは条件分岐命令によって制御されますt。このコマンドは、b FOOラベル ":FOO" に続くコマンドに制御を移します。このt命令は、前回の置換t(または、最初に遭遇した場合はプログラムの開始t)以降に置換が成功した場合にのみ実行されます。

命令は対応する命令までのコマンドブロック{を開始します。ほとんどの場合、ブロックはアドレスパターンによって条件付けられます。 }

フィルターとして

sed はパイプラインフィルタとしてよく使用されます。以下のコマンドラインでは、コマンドは標準出力に「xyz」を書き込み、それがパイプを通して sed に渡され、2行目に示すように「x」が「y」に置き換えられます。 echo

$ echo xyz | sed 's/x/y/g' yyz

スクリプト

スクリプトは、コマンド ライン(-eオプション) で指定するか、ファイル (-fオプション) から読み取ることができます。

コマンドラインでは、シェルが式を単一のトークンとして解釈しない場合にのみ、式を引用符で囲む必要があります。ただし、引用符は通常、明確さを保つために使用され、特に空白文字(例:'s/x x/y y/')の場合など、多くの場合必須です。シェルがシェル変数として解釈するのを避けるため、ほとんどの場合、一重引用符が使用されます。二重引用符(例: )は、シェルがコマンドライン引数や他のシェル変数を代入できるようにするために $使用されます。"s/$1/$2/g"

スクリプトはファイルに保存できます。1行に1つのコマンドを記述します。スクリプトファイルを使用することで、シェルのエスケープや置換に関する問題を回避できます。以下のコマンドラインでは、-fオプションを使用してファイルからコマンドを選択していますsubst.sed

sed -f subst.sed入力ファイル名>出力ファイル名 

スクリプトファイルは、シェバンプレフィックスに続けてコマンドを指定することで、コマンドラインから直接実行することができます。例:

#!/bin/sed -f s / x / y / g

ファイル (subst.sed) は、次のようなコマンドで実行可能にすることができます。

chmod +x置換.sed 

このファイルは次のようにコマンドラインから実行できます。

subst.sed入力ファイル名>出力ファイル名 

インプレース編集

GNU sedで導入されたインプレースオプション(-i)を使用すると、入力ファイルを変更できます。一時的な出力ファイルが作成され、元のファイルがその一時ファイルに置き換えられます。

ファイル内の「yourpassword」をすべて「REDACTED」に置き換えるには、次のようにします。

s / yourpassword /編集済み/ g

「yourword」という単語を含む行を削除するには:

/あなたの言葉/ d

「yourword」という単語のすべてのインスタンスを削除するには:

s / yourword // g

ファイルから 2 つの単語を削除するには:

s /最初の単語// g s / 2 番目の単語// g

前述の例を 1 行で表現するには、たとえばコマンド ラインに入力するときに、セミコロンを使用して 2 つのコマンドを結合します。

s /最初の単語// g ; s /セカンドワード// g

このスクリプトは、2行目が1つのスペースで始まる文から改行を削除します。これは行の結合を示すもので、sedは通常各行を個別に処理するため、注目すべき機能です。これは次のように説明できます。 N;s/\n //;P;D

  • ( N) 次の行をパターンスペースに追加します。
  • ( s/\n / /) スペースが続く改行を検索し、スペース 1 つに置き換えます。
  • ( P) パターンスペースの一番上の行を出力します。
  • ( D) パターンスペースから一番上の行を削除し、スクリプトを再度実行します。

入力テキストの場合:

これは私の犬です。 彼の名前はフランクです。 これは私の魚です 彼の名前はジョージです。 これは私のヤギです 彼の名前はアダムです。 

出力は次のようになります。

これは私の犬です。名前はフランクです。 これは私の魚です 彼の名前はジョージです。 これは私のヤギで、名前はアダムです。 

制限と代替案

sed はシンプルで機能が限られていますが、多くの用途に十分対応できる強力な言語です。より高度な処理を行うには、AWKPerlといったより強力な言語を使用します。これらの言語は、正規表現の抽出やテンプレートの置換よりも複雑な方法で行を変換する場合に特に使用されますが、ホールドバッファを使用することで、原理的には任意の複雑な変換も可能です。

逆に、より単純な操作には、grep(パターンに一致する行を出力)、head(ファイルの最初の部分を出力)、tail(ファイルの最後の部分を出力)、tr(文字の変換または削除)といった特殊なUnixユーティリティが適していることが多いです。これらのユーティリティは、特定のタスクを実行するために設計されているため、sedのような汎用的なソリューションよりも、通常、よりシンプルで明確、そして高速です。

ed/sed のコマンドと構文は、テキストエディタvivimなどの後継プログラムでも引き続き使用されています。ed/sed に類似したものとしてsam /ssam があります。ここで、 sam はPlan 9エディタ、 ssam はそれへのストリームインターフェースであり、sed と同様の機能を提供します。

参照

参考文献

  1. ^ 「sed FAQ、セクション2.1」。2018年6月27日時点のオリジナルよりアーカイブ2013年5月21日閲覧。
  2. ^ 「sed FAQ、セクション2.2」2018年6月27日時点のオリジナルよりアーカイブ2013年5月21日閲覧。
  3. ^ a b McIlroy, MD (1987). A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 (PDF) (技術レポート). CSTR. ベル研究所. 139.
  4. ^ a b c d「Unixの初期の歴史と影響について」しばらくして、置換のための別の特殊用途プログラム、gres(g/re/s)の需要が高まりました。リー・マクマホンはそれの開発を引き受け、すぐにg/re/d、g/re/aなど、このファミリーが尽きることなく続くことを予見しました。彼の構想が発展するにつれて、それはsedへと発展しました…
  5. ^ Raymond, Eric Steven ; Rebe, René (2017-03-03). 「tar-mirror/minised: より小型で、より安価で、より高速なSED実装」 GitHub . 2018-06-13時点のオリジナルからアーカイブ。2024-05-20閲覧
  6. ^ 「Sedスクリプトによるチューリングマシンの実装」 。 2018年2月20日時点のオリジナルよりアーカイブ2003年4月24日閲覧。
  7. ^ "Turing.sed" . 2018年1月16日時点のオリジナルよりアーカイブ2003年4月24日閲覧。
  8. ^ 「$SED ホーム - gamez」
  9. ^ "bolknote/SedChess" . GitHub . 2013年8月23日閲覧
  10. ^ 「Sedtris、sed用に書かれたテトリスゲーム」GitHub2016年10月3日閲覧

さらに読む