\r\n\r\n

linuxでのsedコマンドの使い方

おかしな話ですが、linuxのsedコマンドはインターフェイスのないテキストエディタなんです。コマンドラインから使用して、ファイルやストリーム内のテキストを操作することができます。その力を活用する方法をご紹介します...

おかしな話ですが、Linuxのsedコマンドはインターフェイスのないテキストエディタなのです。コマンドラインから使用して、ファイルやストリーム内のテキストを操作することができます。その力を活用する方法をご紹介します。

セドの力

sedコマンドはチェスのようなもので、基本を学ぶには1時間、マスターするには一生かかります(少なくとも、多くの練習が必要です)。セド機能の主なカテゴリーごとに、開封の儀を紹介します。

sedはパイプ入力やテキストファイルを扱うことができるストリームエディタです。ただし、インタラクティブなテキストエディタ・インターフェースは備えていない。正確には、文章を読むときの指示を与えています。これらは、Bashなどのコマンドラインシェルで使用することができます。

sedでは、以下の全ての操作を行うことができます。

  • テキストを選択する
  • テキストの置き換え
  • テキストに行を追加する
  • テキストから行を削除する
  • オリジナル文書の修正(または保持

私たちは、コンセプトを紹介し、実証するためにサンプルを作成するのであって、最も簡潔な(そして最もアクセスしにくい)sedコマンドを生成するためではありません。しかし、sedのパターンマッチやテキスト選択機能は、正規表現(regex)に大きく依存しています。sedを使いこなすには、これらの知識を身につける必要があります。

関連:Linuxでの正規表現(regex)の使い方

簡単な例

まず、echoを使ってパイプでsedにテキストを送り、sedにその一部を置換させます。そのために、次のように入力します。

echo howtogonk | sed 's/gonk/geek/'

echoコマンドは「howtogonk」をsedに送り、簡単な置換ルール(置換は「s」)を適用する。sedは入力テキストを検索して最初の文字列にマッチするものを探し、その中の任意の文字列を置換する。は2番目の文字列とマッチします。

文字列 "gonk" を "geek" に置き換え、新しい文字列をターミナルウィンドウに表示します。

置換はおそらくsedの最も一般的な使い方ですが、置換を掘り下げる前に、テキストの選択とマッチの方法を知っておく必要があります。

テキストを選択する

この例では、テキストファイルを必要とし、Samuel Taylor Coleridgeの叙事詩「The Ancient Mariner's Mist」からの抜粋を含む詩を使用することにします。

情報を少なくして見るために、次のように入力するのです。

less coleridge.txt

ファイルから何行かを選択するために、選択する範囲の開始行と終了行を指定します。

1行目から4行目までを抜き出すには、次のコマンドを入力します。

sed -n '1,4p' coleridge.txt

1と4の間のカンマに注意してください。pは「一致する行を印刷する」という意味です。デフォルトでは、sedはすべての行を表示します。ファイル内のすべてのテキストが一致した行で2回印刷されることがわかります。これを防ぐために、-n(quiet)オプションを使って、マッチしないテキストを抑制することにします。

別の詩を選択するために、次のように行番号を変更します。

sed -n '6,9p' coleridge.txt

e (expression)オプションで複数選択することができます。2つのexpressionを使って、次のように2つの詩を選択することができます。

sed -n -e '1,4p' -e '31,34p' coleridge.txt

2つ目の式の最初の数字を小さくすると、2つのセクションの間にスペースができます ** 次のように入力します。

sed -n -e '1,4p' -e '30,34p' coleridge.txt

また、開始行を選択し、sedにファイルを走査して5行ごとに1行を表示するか、任意の行数をスキップするように指示することもできます。このコマンドは、上で範囲を選択するのに使ったものと似ています。ただし、今回は数字の区切りにカンマではなく波線記号(~)を使用します。

最初の数字は、スタートラインを示します。2番目の数字は、スタートラインの後のどの列を見たいかをセドに伝える。2は2列目ごと、3は3列目ごと、といった具合です。

以下のように入力します。

sed -n '1~2p' coleridge.txt

探しているテキストがファイルのどこにあるかわからないことが多いので、行番号が必ずしも役に立つとは限りません。しかし、sed を使って、一致するテキストパターンを含む行を選択することもできます。例えば、"And "で始まる行をすべて抽出してみましょう。

記号(^)は、行頭を表します。検索語をフォワードスラッシュ(/)で囲みました。また、「and」の後にスペースを入れることで、「Android」などの単語が検索結果に表示されないようにしています。

sedスクリプトを読むのは、最初は少し難しいかもしれません。pは、上で使ったコマンドと同じように、「印刷」という意味です。しかし、以下のコマンドでは、その前にフォワードスラッシュがあります。

sed -n '/^And /p' coleridge.txt

ファイルから "And "で始まる3行を抜き出して表示する。

リプレースメント

最初の例では、以下のようなsedの置換の基本的な書式を紹介します。

echo howtogonk | sed 's/gonk/geek/'

s は、sed にこれが置き換えであることを伝えます。最初の文字列は検索パターン、2番目の文字列は一致したテキストを置換するテキストです。もちろん、Linuxと同じように、悪魔は細部に宿る。

我々は、「日」を「週」に変更し、船員とアホウドリが接触する時間をより長くするために、次のように入力します。

sed -n 's/day/week/p' coleridge.txt

1行目では、2番目に出てくる "day "のみが変更されています。これは、sedが各行の最初のマッチの後で停止するためである。各行のすべてのマッチを処理するグローバル検索を行うには、以下のように式の末尾に "g "を追加する必要があります。

sed -n 's/day/week/gp' coleridge.txt

これは1行目の4分の3と一致する。最初の単語が "Day" であり、sed は大文字と小文字を区別するため、例の単語が "Day" と同じであるとは考えない

大文字と小文字を区別しないことを示すために、式の最後にコマンドにiを付けて、次のように入力します。

sed -n 's/day/week/gip' coleridge.txt

これは可能ですが、すべてのコンテンツで大文字小文字を区別しないようにしたいとは限らないでしょう。このような場合、正規表現グループを使ってスキーマ特有の大文字・小文字の区別をすることができる。

例えば、文字を角括弧([])で囲むと、"この文字列の中の任意の文字 "として解釈されます。

次のように入力し、「D」と「D」をグループに含めて、「Day」と「Day」の両方に一致するようにします。

sed -n 's/[Dd]ay/week/gp' coleridge.txt

また、ファイルのセクションに限定して置換することも可能です。仮に、このファイルの最初の部分に奇妙な間隔があるとしよう。次のようなおなじみのコマンドで、最初のセクションを表示することができます。

sed -n '1,4p' coleridge.txt

2つのスペースを検索し、1つに置き換えます。この操作をグローバルに行い、ライン全体で繰り返されるようにします。明確には、検索パターンはスペース、スペースアスタリスク(*)で、置換文字列はスペース1つです。

これを次のような順序で並べました。

sed -n '1,4 s/ */ /gp' coleridge.txt

これは素晴らしい機能です。ここで重要なのが検索モードです。アスタリスク(*)は、0個以上の先行する文字、すなわち空白を示す。したがって、検索パターンは、1つ以上のスペースを含む文字列を見つけることである。

複数のスペースからなる任意の並びを1つのスペースに置き換えると、各単語の間に1つのスペースしかない通常のスペースにファイルを戻すことになります。場合によっては、スペースが1つのスペースに置き換えられることもありますが、これは何の悪影響もなく、望む結果を得ることができます。

次のように入力し、検索パターンを1つのスペースに減らすと、なぜ2つのスペースが含まれなければならないかがすぐにわかるだろう。

sed -n '1,4 s/ */ /gp' coleridge.txt

アスタリスクは先行する0個以上の文字にマッチするため、スペース以外のすべての文字を「ゼロスペース」として扱い、置換を適用する。

しかし、2つのスペースが検索パターンに含まれている場合、sedは置換を適用する前に少なくとも1つのスペース文字を見つけなければなりません。これにより、非空白文字がそのまま残るようになります。

先ほど使った-e(式)を使って次のように入力すると、同時に2つ以上の置換ができるようになります。

sed -n -e 's/motion/flutter/gip' -e 's/ocean/gutter/gip' coleridge.txt

2つの式をセミコロン(;)で区切ると、次のように同じ結果になります。

sed -n 's/motion/flutter/gip;s/ocean/gutter/gip' coleridge.txt

以下のコマンドで「日」を「週」に置き換えると、「よく日」という表現に含まれる「日」にも日」のインスタンスも置き換えています。

sed -n 's/[Dd]ay/week/gp' coleridge.txt

これを防ぐには、別のパターンにマッチする行でのみ置換を試みるようにすればよい。コマンドの先頭が検索パターンになるように修正すれば、そのパターンに一致する行の操作だけを考慮することになる。

マッチングパターンを "after "とするために、次のように入力します。

sed -n '/after/ s/[Dd]ay/week/gp' coleridge.txt

これによって、私たちが望んでいた手応えを得ることができました。

より複雑な代替品

Coleridgeを休ませてから、sedを使ってetc/passwdファイルから名前を抜き出してみましょう。

もっと短い方法もありますが(詳しくは後述)、ここでは長い方法を使って、別の概念を示すことにします。検索パターン内の各マッチ(サブ式と呼ばれる)には、番号(最大9項目)を付けることができる。これらの番号は、sedコマンドで特定の部分式を参照するために使用することができます。

部分式は括弧 [()] で囲むと動作します。また、括弧は通常の文字として扱われるのを防ぐため、その前にバックスラッシュ( \)を付けなければならない。

そのためには、次のように入力します。

sed 's/\([^:]*\).*/\1/' /etc/passwd

分解してみよう。

  • sed's/: sedコマンドと置換式の先頭を表す。
  • \を含む左括弧 [(] 内にバックスラッシュ (∕∕)を含む部分式が含まれます。
  • [^:]*: 検索語の最初の部分式に角括弧の中のグループが含まれます。記号(^)は、グループ内で使用する場合、「いいえ」を示す。このグループは、コロン(:)以外の文字もマッチング対象として受け付けることを示しています。
  • \右カギ括弧[]の前にバックスラッシュ(Ⓐ)を付ける。)
  • .*: 2番目の検索部分式は、"任意の文字と任意の数の文字 "を意味します。
  • /type1:式の代入部にバックスラッシュ( \)で始まる1が含まれる場合、最初の部分式にマッチするテキストを示します。
  • /': 右のスラッシュ(/)とシングルクォート(')でsedコマンドを終了させます。

つまり、コロン(:)を含まない文字列を探し、そのコロンがマッチするテキストの最初のインスタンスとなるのです。次に、その行の中にある何かを検索し、それが一致するテキストの2番目のインスタンスとなる。行全体を、最初の部分式にマッチするテキストに置き換えるのです。

etc/passwdファイルの各行は、コロンで終わるユーザー名で始まります。最初のコロンまでのすべてを照合し、行全体をその値で置き換えます。というわけで、ユーザー名を分離しました。

次に、2つ目の部分式を括弧[()]で囲み、番号でも参照できるようにする。また、「▼1」を「▼2」に置換します。 これで、このコマンドは、最初のコロン(:)から行末までをすべて置換することになります。

以下のように入力します。

sed 's/\([^:]*\)\(.*\)/\2/' /etc/passwd

これらの小さな変更がコマンドの意味を変え、ユーザー名以外のすべてを取得することができます。

では、手っ取り早く簡単な方法をご紹介しましょう。

検索語は、最初のコロン(:)から行末までです。置換式が空(//)なので、マッチしたテキストは何も置き換えない。

そこで、最初のコロン(:)から行末までをすべて切り落とし、ユーザー名だけを残して、次のように入力します。

sed 's/:.*//" /etc/passwd

同じコマンドで、1つ目と2つ目のマッチを参照する例を見てみましょう。

姓と名をカンマ(,)で区切ったファイルを用意しました。姓、名」のように記載したいと思います。次のように、catを使ってファイルの中身を見ることができます。

cat geeks.txt

多くのsedコマンドと同様に、次のコマンドも最初は不可解に思えるかもしれません。

sed 's/^\(.*\),\(.*\)$/\2,\1 /g' geeks.txt

これは、他のコマンドと同様の置換コマンドで、検索パターンも非常に単純であるため、以下のように分解している。

  • sedの/:通常の置換コマンド。
  • ^: **記号はグループ([])に含まれないため、"行頭 "を意味する。
  • \(.*),: 最初の部分式は任意の文字数である。括弧[()]で囲まれ、その前にバックスラッシュ(Σ)が付いているので、数字で参照することができる。これまでの全検索パターンは、行頭から最初のカンマ(,)までの任意の文字数を検索するものでした。
  • \(.*): 次の部分式は(再び)任意の数の任意の文字である。また、括弧[()]の中にも含まれており、その両方にはバックスラッシュ( \)が付いているので、一致したテキストを番号で引用することができます。
  • $/:ドル記号($)は行の終わりを示し、行の終わりを検索し続けることができます。これを利用して、ドル記号を簡単に紹介しました。このシナリオでは、アスタリスク(*)が行末に表示されるため、ここでは必要ありません。フォワードスラッシュ(/)で検索パターン部を終了します。
  • \Ί2,Ί1/g':2つの部分式を括弧で囲んだので、その番号で参照することができる。順番を逆にしたいので、2番目に一致するもの、1番目に一致するものとして入力します。数字の前には必ずバックスラッシュ(Ⓐ)を入れてください。
  • /g:このコマンドは、各行に対してグローバルに動作するようにします。
  • Geek.txt:作業しているファイル。

また、「カット」コマンド(c)で、検索パターンに一致する行全体を置き換えることもできます。首」という単語を含む行を検索して、新しい文字列に置き換えるために、次のように入力します。

sed '/neck/c Around my wrist was strung' coleridge.txt

これで、新しい行が抽出ファイルの一番下に表示されるようになりました。

**行とテキスト

また、ファイル内の行やテキストを**新規に追加することもできます。一致する行の後に**新規行を追加するには、Appendコマンド(a)を使用します。

今回取り扱う資料はこちらです。

猫オタク.txt

わかりやすくするために、線に番号を振っています。

He」という単語を含む行を検索し、その下に**改行するために、次のように入力します。

sed '/He/a --> Inserted!' geeks.txt

次のようなコマンドを入力し、一致するテキストを含む行の上に**コマンド(i)〜**改行まで含める。

sed '/He/i --> Inserted!' geeks.txt

一致する行に新しいテキストを追加するには、元の一致するテキストを示すwith記号(&)を使用します。\1, \2, などは、一致する部分式である。

行頭にテキストを追加するには、行のすべてにマッチするreplaceコマンドと、新しいテキストを元の行に結合するreplace句を組み合わせて使用します。

これらのアクションをすべて実行するには、次のように入力します。

sed 's/.*/--> Inserted &/' geeks.txt

各行の間に空白行を追加するGコマンドを含め、以下のコマンドを入力します。

sed 'G' geeks.txt

空白行を2行以上追加する場合は、G;G、G;G、・・・と使用します。

行削除

Deleteコマンド(d)は、検索パターンに一致する行、または行番号や範囲で指定された行を削除するコマンドです。

例えば、3行目を削除する場合は、次のように入力します。

sed '3d' geeks.txt

4行目から5行目までの範囲を削除するには、次のように入力します。

sed '4,5d' geeks.txt

範囲外の行を削除するには、次のように感嘆符(!)を使用します。

sed '6,7!d' geeks.txt

変更を保存する

ここまでで、すべての結果はターミナルウィンドウに出力されましたが、まだどこにも保存されていません。これらのファイルを永続的に使用するには、元のファイルに変更を書き込むか、新しいファイルにリダイレクトしてください。

元のファイルを上書きする際には注意が必要です。sedコマンドが正しくない場合、元に戻すのが困難な変更が元のファイルに加えられることがあります。

安心のために、sedはコマンドを実行する前に元のファイルのバックアップを作成することができます。

In-place オプション (-i) を使用すると、sed に元のファイルに変更を書き込むように指示できますが、ファイル拡張子を追加すると、sed は元のファイルを新しいファイルにバックアップしてしまいます。元のファイルと同じ名前になりますが、新しいファイルの拡張子が付きます。

デモンストレーションとして、"He "という単語を含む行を検索し、削除してみます。また、元のファイルをBAKという拡張子を使った新しいファイルにバックアップします。

これらのアクションをすべて実行するには、次のように入力します。

sed -i'.bak' '/^.*He.*$/d' geeks.txt

バックアップファイルが変更されないように、次のように入力します。

cat geeks.txt.bak

また、以下のコマンドを入力して、出力を新しいファイルにリダイレクトしても、同様の結果を得ることができます。

sed -i'.bak' '/^.*He.*$/d' geeks.txt > new_geeks.txt

新しいファイルに変更が書き込まれたことを確認するために、次のようにcatを使用します。

cat new_geeks.txt

拭き取り

お気づきかもしれませんが、sedのクイックスタートでさえかなり長いです。このコマンドには多くのことがあり、それを使ってさらに多くのことを行うことができます。

しかし、これらの基本的な概念は、あなたがさらに学習を続けるための強固な基礎となることを願っています。

あなたが興味を持っているかもしれない記事

匿名者
匿名者

0 件の投稿

作家リスト

  1. admin 0 投稿
  2. 匿名者 0 投稿

おすすめ