Sed-managing-patterns

提供:Dev Guides
移動先:案内検索

ストリームエディター-パターンの管理

パターンとホールドバッファの使用についてはすでに説明しました。 この章では、それらの使用法について詳しく説明します。 パターンスペースを出力する n コマンドについて説明します。 他のコマンドと組み合わせて使用​​されます。 以下に示すのは、* n *コマンドの構文です。

[address1[,address2]]n

例を挙げましょう。

[jerry]$ sed 'n' books.txt

上記のコードが実行されると、次の結果が生成されます。

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864
*n* コマンドは、パターンバッファーの内容を出力し、パターンバッファーをクリアし、次の行をパターンバッファーにフェッチして、コマンドを適用します。

次のように、 n の前に3つのSEDコマンドがあり、 n の後に2つのSEDコマンドがあると考えてみましょう。

Sed command #1
Sed command #2
Sed command #3
n command
Sed command #4
Sed command #5

この場合、SEDはパターンバッファーに最初の3つのコマンドを適用し、パターンバッファーをクリアして、次の行をパターンバッファーにフェッチし、その後4番目と5番目のコマンドをその上に適用します。 これは非常に重要な概念です。 これを明確に理解せずに先に進まないでください。

ホールドバッファはデータを保持しますが、SEDコマンドをホールドバッファに直接適用することはできません。 したがって、ホールドバッファデータをパターンバッファに取り込む必要があります。 SEDは、パターンの内容を交換してバッファを保持するための x コマンドを提供します。 次のコマンドは、 x コマンドを示しています。

books.txtファイルを少し変更します。 たとえば、ファイルには書籍のタイトルとそれに続く著者名が含まれています。 変更後、ファイルは次のようになります。

[jerry]$ cat books.txt

上記のコードを実行すると、次の結果が得られます。

A Storm of Swords
George R. R. Martin
The Two Towers
J. R. R. Tolkien
The Alchemist
Paulo Coelho
The Fellowship of the Ring
J. R. R. Tolkien
The Pilgrimage
Paulo Coelho
A Game of Thrones
George R. R. Martin

2つのバッファーの内容を交換しましょう。 たとえば、次の例は著者の名前のみを出力します。

[jerry]$ sed -n 'x;n;p' books.txt

上記のコードを実行すると、次の結果が得られます。

George R. R. Martin
J. R. R. Tolkien
Paulo Coelho
J. R. R. Tolkien
Paulo Coelho
George R. R. Martin

このコマンドの仕組みを理解しましょう。

  • 最初に、SEDは最初の行、つまりA Storm of Swordsをパターンバッファに読み込みます。
  • x コマンドは、この行を保持バッファーに移動します。
  • n は次の行、つまりGeorge Rをフェッチします。 R. Martinをパターンバッファーに追加します。
  • 制御はコマンドに渡され、その後にパターンバッファの内容を出力するnが続きます。
  • このプロセスは、ファイルが使い果たされるまで繰り返されます。

次に、印刷の前にバッファの内容を交換しましょう。 どうなってる? はい、書籍のタイトルを印刷します。

[jerry]$ sed -n 'x;n;x;p' books.txt

上記のコードを実行すると、次の結果が得られます。

A Storm of Swords
The Two Towers
The Alchemist
The Fellowship of the Ring
The Pilgrimage
A Game of Thrones
*h* コマンドはホールドバッファを処理します。 パターンバッファからホールドバッファにデータをコピーします。 ホールドバッファからの既存のデータは上書きされます。 *h* コマンドはデータを移動せず、データをコピーするだけであることに注意してください。 したがって、コピーされたデータはパターンバッファーにそのまま残ります。 以下に、 *h* コマンドの構文を示します。
[address1[,address2]]h

次のコマンドは、作者Paulo Coelhoのタイトルのみを出力します。

[jerry]$ sed -n '/Paulo/!h;/Paulo/{x;p}' books.txt

上記のコードを実行すると、次の結果が得られます。

The Alchemist
The Pilgrimage

上記のコマンドがどのように機能するかを理解しましょう。 books.txtの内容は特定の形式に従います。 最初の行は、本のタイトルとそれに続く本の著者です。 上記のコマンドでは、「!」は、条件を逆にするために使用されます。つまり、パターンマッチが成功しなかった場合にのみ、行がホールドバッファにコピーされます。 そして、中括弧\ {}は、複数のSEDコマンドをグループ化するために使用されます

コマンドの最初のパスで、SEDは最初の行、つまりA Storm of Swordsをパターンバッファーに読み込み、パターンPauloが含まれているかどうかを確認します。 パターンマッチは成功しないため、この行をホールドバッファにコピーします。 これで、パターンバッファーとホールドバッファーの両方に同じ行、つまりA Storm of Swordsが含まれます。 2番目のステップでは、行にパターンPauloが含まれているかどうかを確認します。 パターンが一致しないため、何も実行されません。

2番目のパスでは、George Rの次の行を読み取ります。 R. Martinをパターンバッファーに入れ、同じ手順を適用します。 次の3行については、同じことを行います。 5回目のパスの終わりに、両方のバッファーにThe Alchemistが含まれます。 6番目のパスの開始時に、Paulo Coelho行を読み取り、パターンが一致するため、この行をホールドバッファーにコピーしません。 したがって、パターンバッファにはPaulo Coelhoが含まれ、ホールドバッファにはThe Alchemistが含まれます。

その後、パターンバッファにパターンPauloが含まれているかどうかをチェックします。 パターンマッチが成功すると、パターンバッファの内容をホールドバッファと交換します。 これで、パターンバッファにはThe Alchemistが含まれ、ホールドバッファにはPaulo Coelhoが含まれます。 最後に、パターンバッファの内容を出力します。 同じ手順が巡礼のパターンにも適用されます。

*h* コマンドは、保持バッファーの以前の内容を破棄します。 内容を保存する必要がある場合があるため、これは常に受け入れられるとは限りません。 この目的のために、SEDは *H* コマンドを提供します。このコマンドは、最後に新しい行を追加することにより、内容をホールドバッファーに追加します。 *h* コマンドと *H* コマンドの唯一の違いは、前者がホールドバッファーからデータを上書きし、後者がホールドバッファーにデータを追加することです。 構文は *h* コマンドに似ています。
[address1[,address2]]H

別の例を見てみましょう。 今回は、本のタイトルだけを印刷する代わりに、著者の名前も印刷します。 次の例では、書籍名の後に著者名が出力されます。

[jerry]$ sed -n '/Paulo/!h;/Paulo/{H;x;p}' books.txt

上記のコードを実行すると、次の結果が得られます。

The Alchemist
Paulo Coelho
The Pilgrimage
Paulo Coelho

パターンバッファの内容をコピー/追加してバッファを保持する方法を学びました。 逆の機能も実行できますか? はい、確かに! この目的のために、SEDは、ホールドバッファからパターンバッファにデータをコピーする g コマンドを提供します。 コピー中、パターンスペースの既存のデータは上書きされます。 以下に、 g コマンドの構文を示します。

[address1[,address2]]g

同じ例を考えてみましょう-本のタイトルとその著者を印刷します。 今回は、最初に著者の名前を印刷し、次の行に対応する本のタイトルを印刷します。 次のコマンドは、著者のPaulo Coelhoの名前と、その本のタイトルを出力します。

[jerry]$ sed -n '/Paulo/!h;/Paulo/{p;g;p}' books.txt

上記のコードを実行すると、次の結果が得られます。

Paulo Coelho
The Alchemist
Paulo Coelho
The Pilgrimage

最初のコマンドはそのまま保持されます。 5回目のパスの終わりに、両方のバッファーにThe Alchemistが含まれます。 6番目のパスの開始時に、Paulo Coelho行を読み取り、パターンが一致するため、この行をホールドバッファーにコピーしません。 したがって、パターンスペースにはPaulo Coelhoが含まれ、ホールドスペースにはThe Alchemistが含まれます。

その後、パターンスペースにパターンPauloが含まれているかどうかをチェックします。 パターンマッチが成功すると、まずパターンスペースの内容、つまりPaulo Coelhoを出力し、次にホールドバッファーをパターンバッファーにコピーします。 したがって、パターンバッファとホールドバッファの両方にThe Alchemistが含まれています。 最後に、パターンバッファの内容を出力します。 同じ手順が巡礼のパターンにも適用されます。

同様に、ホールドバッファの内容をパターンバッファに追加できます。 SEDには、最後に新しい行を追加してパターンバッファーに内容を追加する G コマンドが用意されています。

[address1[,address2]]G

次に、著者Paulo Coelhoの名前とそれに続く本のタイトルを印刷する前の例を見てみましょう。 同じ結果を得るには、次のSEDコマンドを実行します。

[jerry]$ sed -n '/Paulo/!h;/Paulo/{G;p}' books.txt

上記のコードを実行すると、次の結果が得られます。

Paulo Coelho
The Alchemist
Paulo Coelho
The Pilgrimage

上記の例を修正して、書籍のタイトルの後に著者を表示できますか? 簡単です。 G コマンドの前にバッファの内容を交換するだけです。

[jerry]$ sed -n '/Paulo/!h;/Paulo/{x;G;p}' books.txt

上記のコードを実行すると、次の結果が得られます。

The Alchemist
Paulo Coelho
The Pilgrimage
Paulo Coelho