LinuxでSedStreamEditorを使用してテキストを操作するための基本
序章
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/index
がorg/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
次に、式on
をforward
に置き換えてみましょう。 次のコマンドを使用します。
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
内のon
がforward
に変更されます。
もう1つ注意すべき点は、2行目で2番目のon
がforward
に変更されていないことです。
これは、デフォルトでは、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コマンドを使用してテキストドキュメントをすばやく変換する方法をすでに理解できるはずです。
このシリーズの次の記事では、いくつかのより高度な機能について説明します。