序章

The sed ストリームエディタは、非常に少ない入力で抜本的な変更を加えることができる強力な編集ツールです。 の前回の記事で sedsedを使用してテキストを編集する基本について説明しました。

この記事では、さらに高度なトピックを検討して、紹介を続けます。

:このチュートリアルでは、GNUバージョンの sed Ubuntuおよびその他のLinuxオペレーティングシステムで見つかりました。 macOSを使用している場合は、さまざまなオプションと引数を持つBSDバージョンがあります。 GNUバージョンをインストールできます sed 自作を使用して brew install gnu-sed.

このチュートリアルを完了するには、操作するいくつかのファイルが必要です。これは、最初のチュートリアルから持っている必要があります。 それらがない場合は、次のコマンドを使用して再作成できます。

  1. cd
  2. cp /usr/share/common-licenses/BSD .
  3. echo "this is the song that never ends
  4. yes, it goes on and on, my friend
  5. some people started singing it
  6. not knowing what it was
  7. and they'll continue singing it forever
  8. just because..." > song.txt

さらに、このチュートリアルでは GPL 3ライセンスを使用するため、そのファイルもコピーします。

  1. cp /usr/share/common-licenses/GPL-3 .

お持ちでない場合は、 curl:

  1. curl -o GPL-3 https://www.gnu.org/licenses/gpl-3.0.txt

ファイルができたので、次を使用して探索します sed 複数のコマンドで。

複数の編集シーケンスの提供

複数のコマンドをに渡したい場合がかなりあります sed 同時に。 これを実現する方法はいくつかあります。

以来 sed 標準の入力と出力を介して動作し、さまざまな呼び出しを文字列化できます sed パイプラインを介して一緒に。 このコマンドを実行して、単語を置き換えます and アパーサンド付き(&)、そして単語 peoplehorses:

  1. sed 's/and/\&/' song.txt | sed 's/people/horses/'

「&」は「完全に一致したパターン」を意味するため、エスケープする必要があることに注意してください。 sed):

次の出力が表示されます。

Output
this is the song that never ends yes, it goes on & on, my friend some horses started singing it not knowing what it was & they'll continue singing it forever just because...

これは機能しますが、への複数の呼び出しで不要なオーバーヘッドが発生します sed、より多くのタイピングが必要であり、を利用していません sedの組み込み機能。

さまざまなコマンドを文字列化できます sed を使用して -e 各コマンドの前にオプション。 これは、前のコマンドを書き直す方法です。

  1. sed -e 's/and/\&/' -e 's/people/horses/' song.txt

コマンドをつなぎ合わせる別のアプローチは、セミコロン文字を使用することです(;)個別のコマンドを分離します。 これは前の例と同じように機能しますが、「-e” 必須ではありません:

  1. sed 's/and/\&/;s/people/horses/' song.txt

を使用するときの方法に注意してください -e 構成するには、コマンドごとに個別の単一引用符グループが必要です。 ただし、コマンドをセミコロンで区切る場合、すべてのコマンドは1つの引用符で囲まれたコマンド文字列内に配置されます。 複数のコマンドを表現するこれらの2つの方法は便利ですが、以前の配管技術が依然として必要な場合があります。

考えます = オペレーター。 この演算子は、既存の各行の間の新しい行に行番号を挿入します。 出力は次のようになります。

  1. sed '=' song.txt

表示される出力は次のとおりです。

Output
1 this is the song that never ends 2 yes, it goes on and on, my friend 3 some people started singing it 4 not knowing what it was 5 and they'll continue singing it forever 6 just because...

ただし、テキストを変更して番号の書式を変更したい場合は、期待どおりに機能しないことがわかります。

デモンストレーションのために、 G コマンド。デフォルトでは、各行の間に空白行を入力します(これは実際にはもっと複雑ですが、後で詳しく説明します)。

  1. sed 'G' song.txt

結果は次のとおりです。

Output
this is the song that never ends yes, it goes on and on, my friend some people started singing it not knowing what it was and they'll continue singing it forever just because...

これらの2つのコマンドを組み合わせると、通常の各行と行番号行の間にスペースが必要になる場合があります。

  1. sed '=;G' song.txt

ただし、何か違うものがあります。

Output
1 this is the song that never ends 2 yes, it goes on and on, my friend 3 some people started singing it 4 not knowing what it was . . . . . .

これは、 = オペレーターは、実際の出力ストリームを直接変更します。 これは、結果をさらに編集するために使用できないことを意味します。

あなたは2つを使用することによってこれを回避することができます sed 呼び出し、最初の治療 sed 2番目のテキストの単純なストリームとしての変更:

  1. sed '=' song.txt | sed 'G'

これで、期待していた結果が表示されます。

Output
1 this is the song that never ends 2 yes, it goes on and on, my friend 3 some people started singing it . . . . . .

特に複数のコマンドをつなぎ合わせていて、出力が期待したものと異なる場合は、一部のコマンドがこのように動作することに注意してください。

高度なアドレス指定

の利点の1つ sedのアドレス可能なコマンドは、正規表現を選択基準として使用できることです。 これは、前に見たように、既知のライン値での操作に制限されないことを意味します。

  1. sed '1,3s/.*/Hello/' song.txt
Output
Hello Hello Hello not knowing what it was and they'll continue singing it forever just because...

代わりに、正規表現を使用して、特定のパターンを含む行のみに一致させることができます。 これを行うには、コマンド文字列を指定する前に、2つのスラッシュ(/)の間に一致パターンを配置します。

  1. sed '/singing/s/it/& loudly/' song.txt
Output
this is the song that never ends yes, it goes on and on, my friend some people started singing it loudly not knowing what it was and they'll continue singing it loudly forever just because...

この例では、 loudly の最初の発生後 it 文字列を含むすべての行 singing. 2行目と4行目はパターンと一致しないため、変更されていないことに注意してください。

アドレス指定の式は、任意に複雑にすることができます。 これにより、コマンドの実行に大きな柔軟性がもたらされます。

これは複雑な例ではありませんが、正規表現を使用して他のコマンドのアドレスを生成する方法を示しています。 次のコマンドは、空白行(行の先頭の直後に行の終わりが続く)と一致し、それらを削除コマンドに渡します。

  1. sed '/^$/d' GPL-3

これが表示される出力です。

Output
GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for . . . . . .

範囲の両側でも正規表現を使用できることに注意してください。 たとえば、単語のみを含む行から始まる行を削除できます START 行の読み取りまで END,

たとえば、というファイルを作成します inputfile:

  1. echo "This is an input file
  2. START
  3. this is the text we don't want
  4. END
  5. This is additional text" > inputfile

今すぐ使用 sed 間のコンテンツを削除するには STARTEND:

  1. sed '/^START$/,/^END$/d' inputfile

次の出力が表示されます。

This is an input file
This is additional text

ただし、注意すべき点の1つは、これにより最初からすべてが削除されることです。 START 最初に END、そして別のものに遭遇した場合は削除を再開します START マーカー。

アドレスを反転したい場合(がパターンと一致しない行で操作する)、感嘆符を使用してパターンをたどることができます(!).

たとえば、次のコマンドを使用して、空白ではない行を削除できます(それほど有用ではありませんが、単なる例です)。

  1. sed '/^$/!d' GPL-3

これにより、次のように大きな空白の出力が生成されます。 sed デフォルトでは引き続き行を出力します。

Output

アドレスは、反転するために複雑な式である必要はありません。 反転は、通常の番号付きアドレスでも同じように機能します。

ホールドバッファの使用

増加する機能の1つ sed複数行に対応した編集を実行する機能は、いわゆる「ホールドバッファ」です。 ホールドバッファは、特定のコマンドで変更できる一時ストレージの領域です。

この余分なバッファが存在するということは、他の行で作業しているときに行を保存し、必要に応じて各バッファを操作できることを意味します。

保持バッファに影響を与えるコマンドは次のとおりです。

  • h :現在のパターンバッファー(現在一致して作業している行)を保持バッファーにコピーします(これにより、保持バッファーの以前の内容が消去されます)。
  • H :現在のパターンバッファーを現在の保持パターンの最後に改行(\ n)文字で区切って追加します。
  • g :現在の保持バッファーを現在のパターンバッファーにコピーします。 前のパターンバッファが消去されます。
  • G :現在の保持パターンを現在のパターンバッファーの最後に改行(\ n)文字で区切って追加します。
  • x :現在のパターンと保持バッファーを入れ替えます。

保持バッファの内容は、何らかの方法でパターンバッファに移動されるまで操作できません。

複雑な例を使ってこのアイデアを調べてみましょう。

これは、隣接する線を結合する方法の手順例です(sed 実際には、これの多くを処理する組み込みのコマンドがあります。 The N コマンドは、現在の行に次の行を追加します。 練習のために、難しい方法で物事を行うつもりです):

  1. sed -n '1~2h;2~2{H;g;s/\n/ /;p}' song.txt

表示される出力は次のとおりです。

Output
this is the song that never ends yes, it goes on and on, my friend some people started singing it not knowing what it was and they'll continue singing it forever just because...

これは消化することがたくさんあるので、分解してみましょう。

最初に注意することは、 -n オプションは、自動印刷を抑制するために使用されます。 sed 特に指示した場合にのみ印刷されます。

命令の最初の部分は 1\~2h. 最初はアドレス指定であり、最初の行で後続の操作を実行し、その後、1行おきに(各奇数行)実行することを意味します。 The h partは、一致した行を保持バッファーにコピーするコマンドです。

コマンドの後半はもっと複雑です。 ここでも、アドレス指定から始まります。 今回は、偶数行(最初のコマンドの反対)を参照しています。

コマンドの残りの部分は中括弧で囲まれています。 これは、残りのコマンドが指定されたばかりのアドレスを継承することを意味します。 中括弧がないと、「H」コマンドのみがアドレスを継承し、残りのコマンドはすべての行で実行されます。

The H コマンドは、改行文字に続いて現在のパターンバッファを、現在の保持パターンの最後にコピーします。

この保持パターン(奇数行、改行文字、偶数行)は、パターンバッファー(前のパターンバッファーを置き換える)にコピーされ、 g 指図。

次に、改行文字がスペースに置き換えられ、行が p 指図。

興味がある場合は、 N コマンドはこれをかなり短縮します。 次のコマンドは、今見たのと同じ結果を生成します。

  1. sed -n 'N;s/\n/ /p' song.txt

スクリプトの使用

より複雑なコマンドを使い始めると、テキストエディタでそれらを作成すると役立つ場合があります。 これは、単一のターゲットに適用するコマンドが多数ある場合にも役立ちます。

たとえば、プレーンテキストでメッセージを作成したいが、テキストを使用する前に一連の標準化されたフォーマットを実行する必要がある場合、 sed スクリプトが役立つでしょう。

の各セットを入力する代わりに sed 呼び出し、コマンドをスクリプトに入れて、引数として提供することができます sed. A sed スクリプトは単に生のリストです sed コマンド(通常は一重引用符で囲まれた文字の間の部分)。

これを試すには、という新しいファイルを作成します sed_script 次の内容で:

  1. echo "s/this/that/g
  2. s/people/horses/g
  3. 1,5s/it/that/g" > sed_script

ファイルを保存して、エディターを終了します。

今教えて sed を使用してファイルを使用するには -f スイッチ:

  1. sed -f sed_script song.txt

結果は次のようになります。

Output
that is the song that never ends yes, that goes on and on, my friend some horses started singing that not knowing what that was and they'll continue singing that forever just because...

これにより、すべての編集を1つのファイルに入れて、作成した形式に準拠する必要のある任意のテキストファイルで実行できます。

結論

Sedのコマンドは、最初は必ずしも理解しやすいとは限りません。また、その有用性を理解するには、実際の実験が必要になることがよくあります。 このため、実際に必要になる前に、テキストの操作を練習することをお勧めします。 最終目標を念頭に置き、それを使用してのみ実装してみてください sed.

うまくいけば、この時点で、あなたは適切な習得が持つ力を理解し始めています sed あなたに与えることができます。 あなたがより快適に sed、長期的に行う必要のある作業が少なくなります。