GNU/Linux >> Linux の 問題 >  >> Linux

SEDコマンド入門[初心者向けガイド]

Sedは、60年代の終わりからUnix標準ツールボックスの一部です。他のテキストエディタと同様に、テキストファイルを変更するのに役立ちます。ただし、すでに使用している可能性のあるテキストエディタとは異なり、これは非対話型のエディタです。

つまり、ファイルに適用する変換を事前に指定すると、ツールはそれらの変換を教師なしで適用できます。

ツールの設計目標の最も良い説明は、元のsedペーパーの元の実装のコア開発者であるLeeE.McMahonからのものです。

Sedは、UNIXオペレーティングシステムで実行される非対話型のコンテキストエディタです。 Sedは、次の3つの場合に特に役立つように設計されています。

  1. 大きすぎてインタラクティブに編集しにくいファイルを編集するには;
  2. 編集コマンドのシーケンスが複雑すぎてインタラクティブモードで快適に入力できない場合に、任意のサイズのファイルを編集するには。
  3. 入力を1回通過するだけで、複数の「グローバル」編集機能を効率的に実行できます。

目標の設計(1)と(3)は、おそらく最新のハードウェアとの関連性は低くなりますが、2番目の設計は引き続き有効です。個人的な追加として、sedは、同じ変換を一連のファイルに適用する場合など、反復的なタスクに特に適していると思います。

これらの例で基本的なSEDコマンドを学ぶ

sedの背後にある力を味わうために、プロジェクトの各ソースファイルの上にライセンスヘッダーを追加する必要がある開発者の場合を考えます。

[email protected]:~$ head MIT.LICENSE *.sh
==> MIT.LICENSE <==
-----8<----------------------------------------------------------------
Copyright <YEAR> <COPYRIGHT HOLDER>

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

==> script1.sh <==
#!/bin/bash

echo Hello, I\'m the first script

==> script2.sh <==
#!/bin/bash

cat << EOF
Hello, I'm the second script
EOF

各シェルスクリプトの上にライセンスファイルを表示するだけでなく、年と著作権のプレースホルダーを実際の値に置き換えてほしいと思います。それが私たちの最初のユースケースになります。

注:自分で練習したい場合は、私のWebサイトからサンプルファイルをダウンロードできます。この記事を完成させるビデオもご覧ください:

1。 SEDのテキストを置き換える

ライセンスファイルで、およびプレースホルダーを実際の値に置き換えたいと思います。

これは、sed substitutionに最適な仕事です。 指図。おそらくすべてのsedコマンドの中で最も便利です:

[email protected]:~$ sed -e 's/<YEAR>/2018/' MIT.LICENSE  | head -5
-----8<----------------------------------------------------------------
Copyright 2018 <COPYRIGHT HOLDER>

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

パイプを使用する( | )、sedコマンドの出力を headに転送しました ここに最初の5行だけを表示するツール。ただし、今日の特定のトピックで最も興味深い部分は、 s / / 2018 /です。 表現。

Sedは、入力ファイルを一度に1行ずつ処理することで機能します。各行で、代替( s )コマンドは、最初の2つのスラッシュ( / / )の間のテキストの最初の出現を置き換えます )最後の2つの間のテキスト( / 2018 / )。これは、GUIテキストエディタにある検索-置換機能のように考えてください。

ここで言及する価値があるのは、元のMIT.LICENSEファイルが変更されていないことです。次のコマンドを使用して、自分で確認します。

head -5 MIT.LICENSE

2。テキストを置き換える…もう一度

すばらしい:年のプレースホルダーを置き換えました。しかし、置き換えるものが2つあります。前の例を理解していれば、おそらく次のような2番目のsed式を想像できます。

's/<COPYRIGHT HOLDER>/Sylvain Leroux/'

しかし、それをどこに配置するのでしょうか?さて、あなたにはいくつかの選択肢があります。リダイレクトの概念に既に精通している場合に最も明白なのは、最初のsedコマンドの出力をsedの2番目のインスタンスにパイプすることです。

[email protected]:~$ sed -e 's/<YEAR>/2018/' MIT.LICENSE  |
    sed -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' |
    head -5
----8<----------------------------------------------------------------
Copyright 2018 Sylvain Leroux

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

しかし、私たちはもっとうまくやることができます。 -e以降 オプションはsed式を導入し、それらのいくつかを同じsed呼び出しの一部として使用でき、結果は同じになります:

# Pay special attention to the \ at the end of the lines
# specifying the *same* command continues on the
# next line:
sh$ sed -e 's/<YEAR>/2018/'  \
                -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
                MIT.LICENSE |
        head -5

最後に、新しい行で区切ることにより、同じsed式で複数のコマンドを指定することもできます。これは、より複雑なsedプログラムを書き始めるときに特に役立ちます。

# Pay special attention to the single-quotes and
# backslash placement:
sh$ sed -e 's/<YEAR>/2018/
            s/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        MIT.LICENSE |
    head -5

3。テキストの挿入

これで、プレースホルダーが実際の値に置き換えられました。ただし、そのライセンスファイルをプロジェクトファイルに挿入できるようになるまでには、まだやるべきことがいくつかあります。後でシェルスクリプトになるため、ライセンスの各行はoctothorp()で始まる必要があります。 )シェルが理解するために、それらの行を解釈しようとすべきではありません。

そのために、置換コマンドを再度使用します。以前に言及しなかったことは、GUIエディターのほとんどの検索置換機能とは異なり、検索パターンは必ずしも検索するリテラル文字列ではないということです。実際、これは正規表現(regex)です。つまり、逐語的に一致するプレーンな文字に加えて、特別な意味を持つ文字を使用することができます。たとえば、キャレット( ^ )は行の先頭であるドル記号( $ を表します )行の終わり、または最後の例として、ドットスター(。* )は、0、1、または複数の文字の任意のシーケンスを意味します。そのようなメタ文字は他にもたくさんありますが、今のところ、これで十分です。

したがって、挿入するには 行頭にテキストがあります。オプションは置換です。 そのテキストによる行の先頭:

[email protected]:~$ sed -e 's/<YEAR>/2018/'  \
        -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        -e 's/^/# /' \
        MIT.LICENSE | head -5
# -----8<----------------------------------------------------------------
# Copyright 2018 Sylvain Leroux
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the

4。選択した行をクリアする

sedの置換コマンドは非常に用途が広いため、それを使用してほとんどのテキスト変換を表現できます。たとえば、ライセンステキストの上下にある破線を削除するには、次のように記述します。

[email protected]:~$ sed -e 's/<YEAR>/2018/'  \
        -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        -e 's/^/# /' \
        -e 's/^.*----.*$//' \
        MIT.LICENSE | head -5

# Copyright 2018 Sylvain Leroux
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the

その後の置換は、すべてのテキストが空の文字列に置き換えられました:

シンボル 説明
^ 行の先頭から開始
。* 0、1、または複数の文字の任意のシーケンスが続く
---- 4つのハイフンが続く
。* 0、1、または複数の文字の任意のシーケンスが続く
$ 行の終わりが続きます

つまり、これにより、行全体が空の文字列 if に置き換えられます。 4つのダッシュが連続して含まれています。ただし、空の行自体は出力に残り、空白行として表示されます。

正確なニーズと好みに応じて、以下の代替ソリューションを検討することもできます。これを詳細に調べて、コマンドの変更を特定し、結果にどのような影響があったかを自分で特定します。

[email protected]:~$ sed -e 's/<YEAR>/2018/'  \
        -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        -e 's/^.*----.*$//' \
        -e 's/^/# /' \
        MIT.LICENSE | head -5

行をクリアするために使用される正規表現が少し複雑すぎる場合は、別のsed機能を利用することもできます。ほとんどすべてのコマンドは、コマンド名の前にオプションのアドレスを取ることができます。存在する場合は、コマンドの範囲を matchingの行に制限します。 そのアドレス:

[email protected]:~$ sed -e 's/<YEAR>/2018/'  \
        -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        -e 's/^/# /' \
        -e '/----/s/^.*$//' \
        MIT.LICENSE | head -5

これで、最新の置換コマンドは、4つのダッシュが連続して一致する(つまり「含む」)行にのみ適用されます。そして、一致する行ごとに、すべてが置き換えられます(。* )開始間( ^ )と終了( $ )空の文字列( //

5。選択した行を削除する

前のセクションでは、置換コマンドを微調整して、テキストの一部の行をクリアしました。しかし、空の行は残っていました。これが望ましい場合もあります。時々そうではありません。後者の場合、削除を調査することをお勧めします。 出力から行全体を削除するコマンド:

# Below, the redirection '> LICENSE' is used to store
# the result of the sed command into the newly
# created LICENSE file:
[email protected]:~$ sed -e 's/<YEAR>/2018/'  \
        -e 's/<COPYRIGHT HOLDER>/Sylvain Leroux/' \
        -e 's/^/# /' \
        -e '/----/d' \
        MIT.LICENSE > LICENSE
[email protected]:~$ head -5 LICENSE
# Copyright 2018 Sylvain Leroux
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including

d 削除です コマンド名。 sと同じように 置換でした コマンド名。ここでは、コマンドの前にアドレスを指定したため、一致する行のみが削除されます(アドレスなし、 d コマンドはファイルのすべての行を削除します)

6。大文字に変換

これまでは、主にライセンスファイルの先頭に焦点を当てていました。しかし、確かに、ドキュメントに対してもう少し実行したい変更がいくつかあります。最初に私が話していることを見てみましょう:

[email protected]:~$ sed -ne '/The above/,$p' LICENSE
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# The software is provided "as is", without warranty of any kind,
# express or implied, including but not limited to the warranties of
# merchantability, fitness for a particular purpose and noninfringement.
# In no event shall the authors or copyright holders be liable for any
# claim, damages or other liability, whether in an action of contract,
# tort or otherwise, arising from, out of or in connection with the
# software or the use or other dealings in the software.

上記のコマンドで、-nオプションを使用して、パターンスペースの自動印刷を無効にしました。つまり、明示的に要求しない限り、sedは出力に何も出力しなくなります。これはまさに私がprint(p)コマンドを使用して行うことです。 pコマンドの前に単一のアドレスを使用する代わりに、 rangeを使用したことに注意してください。 「上記」というテキストを含む行とドキュメントの終わり($)の間にテキストを表示します。

printコマンドは、ファイルの一部を抽出する必要がある場合に役立ちます。ただし、今日は、最後の2つの段落を表示して、今必要なものを説明したいと思います。これはライセンスファイルの伝統であるため、ソフトウェアが「現状のまま」提供されることを明確にすることで自分自身をカバーしたいと思います。したがって、最後の段落(「ソフトウェア」で始まる)をすべて大文字で書き直して強調したいと思います。

置換コマンドの置換部分で、&は検索パターンに一致するテキストに置換されます。 \ U GNU拡張子を使用して、置換文字列の大文字と小文字を変更できます:

[email protected]:~$ sed -i -e '/The software/,$s/.*/\U&/' LICENSE
[email protected]:~$ cat LICENSE

プレーンテキストのs/.*/\U&/ 「任意のテキストを置き換える(。* )大文字( \ U )それ自体のバージョン( )。自分で確認させてください。最後の段落はすべて大文字で書く必要があります。ちなみに、 -iのせいでお気づきかもしれません フラグを立てると、変更はLICENSEファイルに直接適用されました。

これについては、次のセクションで詳しく説明します。それまでの間、私はあなたにそれらのコマンドをあなたの意志で練習して修正させます。好みに合ったライセンスファイルを入手したら、プロジェクトの各ソースファイルの前にそれを含める方法を確認します。

7。テキストファイルの挿入

ここで複雑なコマンドを期待している場合は、がっかりします。ファイルを別のファイルに挿入するのは非常に簡単です:

sed -i -e '1r LICENSE' script1.sh
cat script1.sh

ここで確認する2つのこと:

  1. r LICENSE 式は、読み取るコマンドです。 現在処理中のファイルに外部ファイルを挿入します。ここでは、番号 1が接頭辞として付けられています これは、入力ファイルの1行目のみに一致するアドレスです。
  2. -i オプションを使用すると、ファイルをその場で変更できます 。つまり、sedはバックグラウンドで一時ファイルを作成してその出力をそこに保存し、処理が完了すると、元のファイルを変更されたファイルに置き換えます。

「-i」オプションの興味深い副作用は、コマンドラインで複数のファイル名を指定できることです。sedはそれぞれに同じ変換を独立して適用します。

sed -i -e '1r LICENSE' *.sh

8。バック・トゥ・ザ・フューチャー

sedコマンドの最後の例として、数年が経過し、現在2024年1月1日であると想像してみてください。すべてのファイルの著作権表示を更新する必要があります。プロジェクトファイルがいつ作成されたかに応じて、いくつかのユースケースがあります。したがって、著作権に関する通知は、次の2つの形式のいずれかに従う必要があります。

現在の著作権 説明
著作権2023 昨年作成されたファイルの場合
著作権2018-2023 昨年より前に作成されたファイルの場合

拡張(-E)正規表現を使用して、これら2つのユースケースを一度にキャプチャできます。ここで実際に使用する「拡張」されたものは、括弧だけです。

sed -i -Ee 's/Copyright (....)(-....)?/Copyright \1-2024/' *.sh

* .shファイルの著作権表示を手動で変更してから、さまざまな使用例で上記のコマンドを実行して、どのように機能するかを確認することをお勧めします。

私が言うなら、検索パターンで、それは最終的にあなたの理解を助けるかもしれません:Copyright::は逐語的に一致するリテラルテキストです。 (…。)::4つの任意の文字に一致するキャプチャグループを定義します。うまくいけば、1年の4桁。 (-…。)?::ダッシュとそれに続く4つの任意の文字に一致するキャプチャグループを定義します。最後の疑問符は、グループがオプションであることを示しています。入力行に存在する場合と存在しない場合があります。

置換文字列:Copyright ::は、逐語的にコピーされるリテラルテキストです。 \ 1 ::は、最初のキャプチャグループのコンテンツです。-2024::は、逐語的にコピーされるリテラルテキストです。

時間をかけて自分でコマンドを確認した場合は、前の表で説明したユースケースにそれらのルールを適用するかどうかを確認する必要があります。次のようなものが得られます。

一致するテキスト \ 1 \ 2 置換文字列
著作権2023 2023 著作権2023-2024
著作権2018-2023 2018 -2023 著作権2018-2024

SEDガイドを締めくくる

ここでは表面を引っかいただけです。 sed ツールはそれよりもはるかに強力です。ただし、4つのコマンド( s )しか見たことがない場合でも 、 p d 、および i )およびいくつかの基本的な正規表現構造( ^ $ および。* )、あなたはすでに多くのを解決するのに十分な知識を持っています 日々の問題。

少しチャレンジしてチュートリアルを終了するのが好きなので、ここに提案します。サポート資料をダウンロードした場合は、プロジェクトのディレクトリに hello.cという名前のファイルがあります。 。これは基本的なCプログラムのソースファイルです:

[email protected]:~$ ls
hello.c  MIT.LICENSE  script1.sh  script2.sh
[email protected]:~$ gcc hello.c -o hello
[email protected]:~$ ./hello sylvain
Hello sylvain
[email protected]:~$ cat hello.c

ソースファイルにはすでにいくつかのコメントがあります。それらをCプログラミング言語のコメント構文の例として使用することにより、MITライセンスを hello.cに挿入できますか。 sedコマンドを使用したソースファイル? 1つまたは複数のsedコマンドを使用でき、sedコマンドの出力を別のコマンドにパイプできます。必要に応じて一時ファイルを使用できますが、 sed以外のコマンドを使用できます。もちろん、ライセンスを挿入した後でも、Cソースファイルはコンパイルされます!

ここで、その小さな問題について考えさせてください。その記事とそのコンパニオンビデオを楽しんでいただけたと思います。 sedについて詳しく知りたい場合は、コメントセクションを使用してお知らせください。


Linux
  1. Zshの使用を開始する

  2. Linuxtacコマンドの使用を開始する

  3. Linuxcatコマンドの使用を開始する

  1. lsの使用を開始する

  2. LinuxでPostgreSQLを使い始める

  3. マルチパス入門–UbuntuVMの実行

  1. GnuCashの使用を開始する

  2. Etcher.ioを使い始める

  3. 正規表現を使い始める