LinuxでSedStreamEditorを使用してテキストを操作するための基本

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

序章

sedコマンドは、ストリームエディタの略で、標準の入力またはファイルからのテキストに対して編集操作を実行します。 sedは、行ごとに非対話型の方法で編集します。

これは、コマンドを呼び出すときにすべての編集決定を行い、sedが指示を自動的に実行することを意味します。 これは紛らわしい、または直感的ではないように思われるかもしれませんが、特にスクリプトまたは自動ワークフローの一部として、テキストを変換するための非常に強力で高速な方法です。

このチュートリアルでは、いくつかの基本的な操作について説明し、このエディターの操作に必要な構文を紹介します。 通常のテキストエディタをsedに置き換えることはほぼ確実ではありませんが、テキスト編集ツールボックスへの追加として歓迎されるでしょう。

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


インタラクティブターミナルを起動します!

基本的な使用法

sedは、テキストファイルまたは標準入力(STDIN)から読み取るテキストストリームを操作します。 これは、別のコマンドの出力を直接sedに送信して編集したり、作成済みのファイルで作業したりできることを意味します。

sedは、デフォルトですべてを標準出力(STDOUT)に出力することにも注意してください。 つまり、リダイレクトされない限り、sedは出力をファイルに保存するのではなく、画面に出力します。

基本的な使用法は次のとおりです。

sed [options] commands [file-to-edit]

このチュートリアルでは、BSDソフトウェアライセンスのコピーを使用してsedを試してみます。 Ubuntuでは、次のコマンドを実行してBSDライセンスファイルをホームディレクトリにコピーし、操作できるようにします。

cd
cp /usr/share/common-licenses/BSD .

BSDライセンスのローカルコピーがない場合は、次のコマンドを使用して自分で作成します。

cat << 'EOF' > BSD
Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors
   may be used to endorse or promote products derived from this software
   without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
EOF

sedを使用して、BSDライセンスファイルの内容を表示してみましょう。 sedはデフォルトで結果を画面に送信します。つまり、編集コマンドを渡さなくてもファイルリーダーとして使用できます。 次のコマンドを実行してみてください。

sed '' BSD

画面にBSDライセンスが表示されます。

OutputCopyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
...
...

一重引用符には、sedに渡す編集コマンドが含まれています。 この場合、何も渡さなかったので、sedは受け取った各行を標準出力に出力しました。

sedは、ファイルではなく標準入力を使用できます。 catコマンドの出力をsedにパイプして、同じ結果を生成します。

cat BSD | sed ''

ファイルの出力が表示されます。

OutputCopyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
. . .
. . .

ご覧のとおり、パイプ(|)文字を使用して出力をパイプするときに生成されるもののように、ファイルまたはテキストのストリームを簡単に操作できます。

印刷ライン

前の例では、操作なしでsedに渡された入力が、結果を直接標準出力に出力することを確認しました。

sedの明示的なprintコマンドを調べてみましょう。このコマンドは、一重引用符で囲まれたp文字を使用して指定します。

次のコマンドを実行します。

sed 'p' BSD

BSDファイルの各行が2回印刷されているのがわかります。

OutputCopyright (c) The Regents of the University of California.
Copyright (c) The Regents of the University of California.
All rights reserved.
All rights reserved.


Redistribution and use in source and binary forms, with or without
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
modification, are permitted provided that the following conditions
are met:
are met:
. . .
. . .

sedはデフォルトで各行を自動的に印刷し、次に「p」コマンドで行を明示的に印刷するように指示したので、各行が2回印刷されます。

出力を詳しく調べると、最初の行が2回、次に2番目の行が2回あるなど、sedがデータ行ごとに動作していることがわかります。 行を読み取り、操作し、結果のテキストを出力してから、次の行でプロセスを繰り返します。

-nオプションをsedに渡すと、結果をクリーンアップできます。これにより、自動印刷が抑制されます。

sed -n 'p' BSD
OutputCopyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
. . .
. . .

これで、各行を1回印刷することに戻ります。

これまでの例は、編集とはほとんど考えられません(各行を2回印刷したい場合を除いて…)。 次に、sedがテキストデータの特定のセクションをターゲットにして、出力を変更する方法について説明します。

アドレス範囲の使用

アドレスを使用すると、テキストストリームの特定の部分をターゲットにできます。 特定の行または行の範囲を指定することもできます。

sedにファイルの最初の行を印刷させましょう。 次のコマンドを実行します。

sed -n '1p' BSD

最初の行が画面に印刷されます。

OutputCopyright (c) The Regents of the University of California.

印刷コマンドの前に番号1を配置することにより、操作する行番号をsedに指示しました。 5行も簡単に印刷できます(「-n」を忘れないでください)。

sed -n '1,5p' BSD

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

OutputCopyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

sedにアドレス範囲を指定しました。 sedにアドレスを指定すると、それらの行に続くコマンドのみが実行されます。 この例では、1行目から5行目までを印刷するようにsedに指示しました。 これを別の方法で指定するには、最初のアドレスを指定してから、オフセットを使用して、次のように、移動する追加の行の数をsedに通知します。

sed -n '1,+4p' BSD

sedに1行目から開始し、次の4行でも操作するように指示したため、これは同じ出力になります。

1行おきに印刷する場合は、~文字の後に間隔を指定してください。 次のコマンドは、BSDファイルの1行目から1行おきに出力します。

sed -n '1~2p' BSD

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

OutputCopyright (c) The Regents of the University of California.

modification, are permitted provided that the following conditions
1. Redistributions of source code must retain the above copyright
2. Redistributions in binary form must reproduce the above copyright
    documentation and/or other materials provided with the distribution.
    may be used to endorse or promote products derived from this software
. . .
. . .

sedを使用して、出力からテキストを削除することもできます。

テキストの削除

pコマンドをdコマンドに変更することにより、以前にテキスト印刷を指定していた場所でテキストの削除を実行できます。

この場合、sedは削除されていないものをすべて出力するため、-nコマンドは不要になります。 これは、何が起こっているかを確認するのに役立ちます。

前のセクションの最後のコマンドを変更して、最初の行から始まる1行おきに削除するようにします。

sed '1~2d' BSD

その結果、前回ではなくであったすべての行が表示されます。

OutputAll rights reserved.
Redistribution and use in source and binary forms, with or without
are met:
    notice, this list of conditions and the following disclaimer.
    notice, this list of conditions and the following disclaimer in the
3. Neither the name of the University nor the names of its contributors
    without specific prior written permission.
. . .
. . .

ここで重要なのは、ソースファイルは影響を受けていないということです。 それはまだ無傷です。 編集内容が画面に出力されます。

編集内容を保存する場合は、次のように標準出力をファイルにリダイレクトできます。

sed '1~2d' BSD > everyother.txt

次に、catでファイルを開きます。

cat everyother.txt

以前に画面に表示されたものと同じ出力が表示されます。

OutputAll rights reserved.
Redistribution and use in source and binary forms, with or without
are met:
    notice, this list of conditions and the following disclaimer.
    notice, this list of conditions and the following disclaimer in the
3. Neither the name of the University nor the names of its contributors
    without specific prior written permission.
. . .
. . .

sedコマンドはデフォルトではソースファイルを編集しませんが、-iオプションを渡すことでこの動作を変更できます。これは、「インプレースで編集を実行する」ことを意味します。 これにより、ソースファイルが変更されます。

警告-iスイッチを使用すると元のファイルが上書きされるため、注意して使用する必要があります。 最初に-iスイッチを使用せずに操作を実行し、必要なものが得られたら-iを使用してコマンドを再実行するか、元のファイルのバックアップを作成するか、出力をファイルにリダイレクトします。 -iスイッチを使用して誤って元のファイルを変更するのは非常に簡単です。


作成したeveryother.txtファイルをインプレースで編集してみてください。 1行おきにもう一度削除して、ファイルをさらに減らしましょう。

sed -i '1~2d' everyother.txt

catを使用してcat everyother.txtでファイルを表示すると、ファイルが編集されていることがわかります。

-iオプションは危険にすることができます。 ありがたいことに、sedを使用すると、編集前にバックアップファイルを作成できます。

編集前にバックアップファイルを作成するには、「-i」オプションの直後にバックアップ拡張子を追加します。

sed -i.bak '1~2d' everyother.txt

これにより、拡張子が.bakのバックアップファイルが作成され、元のファイルがインプレースで編集されます。

次に、sedを使用して検索および置換操作を実行する方法を見ていきます。

テキストの置換

おそらく、sedの最もよく知られている使用法は、テキストを置き換えることです。 sedは、正規表現を使用してテキストパターンを検索し、見つかったテキストを別のものに置き換えることができます。

LinuxでのGrep正規表現を使用したテキストパターンの検索に従って、正規表現の詳細を学ぶことができます。

最も基本的な形式では、次の構文を使用して1つの単語を別の単語に変更できます。

's/old_word/new_word/'

sは代替コマンドです。 3つのスラッシュ(/)は、異なるテキストフィールドを区切るために使用されます。 さらに役立つ場合は、他の文字を使用してフィールドを区切ることができます。

たとえば、Webサイト名を変更しようとしている場合、URLにはスラッシュが含まれているため、別の区切り文字を使用すると便利です。

次のコマンドを実行して、echoでURLを出力し、アンダースコア(_)文字を区切り文字として使用してsedで変更します。

echo "http://www.example.com/index.html" | sed 's_com/index_org/home_'

これにより、com/indexorg/homeに置き換えられます。 出力には、変更されたURLが表示されます。

Outputhttp://www.example.org/home.html

最後の区切り文字を忘れないでください。そうしないと、sedが文句を言います。 このコマンドを実行した場合:

echo "http://www.example.com/index.html" | sed 's_com/index_org/home'

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

Outputsed: -e expression #1, char 20: unterminated `s' command

いくつかの置換を練習するために新しいファイルを作成しましょう。 次のコマンドを実行して、song.txtという名前の新しいテキストファイルを作成します。

echo "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..." > song.txt

次に、式onforwardに置き換えてみましょう。 次のコマンドを使用します。

sed 's/on/forward/' song.txt

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

Outputthis is the sforwardg that never ends
yes, it goes forward and on, my friend
some people started singing it
not knowing what it was
and they'll cforwardtinue singing it forever
just because...

ここでいくつかの注目すべき点を見ることができます。 まず、sedが単語ではなく、パターンを置き換えたことです。 song内のonforwardに変更されます。

もう1つ注意すべき点は、2行目で2番目のonforwardに変更されていないことです。

これは、デフォルトでは、sコマンドが行の最初の一致で動作し、次に次の行に移動するためです。 sedを各行の最初のインスタンスだけでなく、onのすべてのインスタンスに置き換えるには、代替コマンドにオプションのフラグを渡す必要があります。

gフラグを置換セットの後に配置して、置換コマンドに提供します。

sed 's/on/forward/g' song.txt

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

Outputthis is the sforwardg that never ends
yes, it goes forward and forward, my friend
some people started singing it
not knowing what it was
and they'll cforwardtinue singing it forever
just because...

これで、substituteコマンドはすべてのインスタンスを変更します。

sedが各行で検出した「on」の2番目のインスタンスをonlyで変更したい場合は、gの代わりに番号2を使用します。

sed 's/on/forward/2' song.txt

今回は、2回目の出現がないため、他の行は変更されていません。

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

置き換えられた行だけを確認したい場合は、-nオプションを再度使用して、自動印刷を抑制します。

次に、pオプションをsubstituteコマンドに渡して、置換が行われた行を印刷できます。

sed -n 's/on/forward/2p' song.txt

変更された行が画面に印刷されます。

Outputyes, it goes on and forward, my friend

ご覧のとおり、コマンドの最後でフラグを組み合わせることができます。

検索プロセスで大文字と小文字を区別しないようにする場合は、「i」フラグを渡すことができます。

sed 's/SINGING/saying/i' song.txt

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

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

一致したテキストの置き換えと参照

正規表現を使用してより複雑なパターンを見つけたい場合は、置換テキストで一致したパターンを参照するためのさまざまな方法があります。

たとえば、行の先頭からatに一致させるには、次のコマンドを使用します。

sed 's/^.*at/REPLACED/' song.txt

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

OutputREPLACED never ends
yes, it goes on and on, my friend
some people started singing it
REPLACED it was
and they'll continue singing it forever
just because...

ワイルドカード式が行の先頭からatの最後のインスタンスまで一致していることがわかります。

検索文字列で一致する正確なフレーズがわからないため、&文字を使用して、置換文字列で一致したテキストを表すことができます。

一致したテキストを括弧で囲みましょう。

sed 's/^.*at/(&)/' 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...

一致したテキストを参照するより柔軟な方法は、エスケープされた括弧を使用して、一致したテキストのセクションをグループ化することです。

括弧でマークされた検索テキストのすべてのグループは、エスケープされた参照番号で参照できます。 たとえば、最初の括弧グループは\1で参照でき、2番目の括弧グループは\2で参照できます。

この例では、各行の最初の2つの単語を切り替えます。

sed 's/\([a-zA-Z0-9][a-zA-Z0-9]*\) \([a-zA-Z0-9][a-zA-Z0-9]*\)/\2 \1/' song.txt

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

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

ご覧のとおり、結果は完全ではありません。 たとえば、2行目は、文字セットにリストされていない文字が含まれているため、最初の単語をスキップします。 同様に、they'llを5行目の2つの単語として扱いました。

より正確になるように正規表現を改善しましょう。

sed 's/\([^ ][^ ]*\) \([^ ][^ ]*\)/\2 \1/' song.txt

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

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

これは前回よりもはるかに優れています。 これにより、句読点が関連する単語とグループ化されます。

括弧内で式を繰り返す方法に注意してください(*文字なしで1回、次にそれ付きで1回)。 これは、*文字が、その前にある文字セットと0回以上一致するためです。 これは、パターンが見つからない場合でも、ワイルドカードとの一致が「一致」と見なされることを意味します。

sedがテキストを少なくとも1回検出するようにするには、ワイルドカードを使用する前に、ワイルドカードなしで1回一致させる必要があります。

結論

このチュートリアルでは、sedコマンドについて説明しました。 ファイルから特定の行を印刷し、テキストを検索し、行を削除し、元のファイルを上書きし、正規表現を使用してテキストを置き換えました。 適切に構築されたsedコマンドを使用してテキストドキュメントをすばやく変換する方法をすでに理解できるはずです。

このシリーズの次の記事では、いくつかのより高度な機能について説明します。