ターミナルあり:正規表現の使用II:置換

私自身で 前の記事 基本的なレベルで、正規表現で最もよく使用される特殊文字がどのように機能するかを説明しました。 これらの正規表現を使用すると、テキストファイルや他のコマンドの出力で複雑な検索を行うことができます。 この記事では、sedコマンドを使用して、テキストを単に別のテキストに変更するよりもはるかに強力な方法でテキストを検索して置換する方法について説明します。

grepコマンドについてもう少し

sedについて話し始める前に、grepコマンドについてもう少しコメントして、前の記事で説明したことを少し完了させたいと思います。 私が言おうとしていることはすべて、これにも関連するでしょう。 後で、これと検索の関係を確認します。

正規表現の組み合わせ

前回の記事でお話しした特殊文字の多くは、他の文字だけでなく、正規表現全体と組み合わせることができます。 これを行う方法は、括弧を使用して部分式を形成することです。 この例を見てみましょう。 テストに使用できるテキストをダウンロードすることから始めましょう。 フレーズのリストです。 そのために、次のコマンドを使用します。

curl http://artigoo.com/lista-de-frases-comparativas-comicas 2>/dev/null | sed -n 's/.*\(.*\.\)<\/p>/\1/gp' > frases

 これにより、«phrases»という名前のファイルを起動するディレクトリに移動します。 あなたはそれを開いて見て、少し笑うことができます。 🙂

ここで、正確に6語のフレーズを検索するとします。 難しいのは、各単語に一致する正規表現を作成することです。 単語は大文字または小文字の文字のシーケンスであり、次のようになります。 '[a-zA-Z]+'、ただし、これらの文字は文字以外の文字で区切る必要があることも指定する必要があります。つまり、次のようになります。 '[a-zA-Z]+[^a-zA-Z]+'。 注意:角かっこ内の最初の文字としての「^」は、範囲内にない文字と一致させたいことを示し、「+」は1つ以上の文字を示します。

単語に一致する正規表現はすでにあります。 6とペアリングするには、6回繰り返す必要があります。 そのためにキーを使用しましたが、置くのは無意味です '[a-zA-Z]+[^a-zA-Z]+{6}'、6は正規表現の最後の部分を繰り返すので、必要なのはそれをすべて繰り返すことなので、入力する必要があるのは次のとおりです。 '([a-zA-Z]+[^a-zA-Z]+){6}'。 括弧を使用して部分式を形成し、中括弧を使用してそれを6回繰り返します。 ここで、行全体に一致するように、前に「^」を追加し、後ろに「$」を追加する必要があります。 コマンドは次のとおりです。

grep -E '^([a-zA-Z]+[^a-zA-Z]+){6}$' frases

そして、結果はまさに私たちが望んでいたものです。

マカレナよりも歌われています。 あなたはルイス・アギレよりも完成度が高いです。 あなたは石よりも文化が少ない。 あなたはCañitaBravaよりも多くの言語を知っています。 彼はツタンカーメンよりもしわが多い。 あなたはランボーよりも育児についてあまり知らない。

「+」を機能させるために拡張正規表現を使用するため、-Eパラメーターを設定していることに注意してください。 基本的なものを使用した場合、括弧と中括弧をエスケープする必要があります。

後方参照または後方参照

スペルチェッカーがインストールされている場合は、おそらく単語のリストがあります /usr/share/dict/words。 そうでない場合は、次の方法でarchにインストールできます。

sudo pacman -S words

またはDebianで:

sudo aptitude install dictionaries-common

必要に応じて、ファイルを見て、その単語が何であるかを確認できます。 実際には、ディストリビューションが存在する言語の単語ファイルへのリンクです。 複数のWordファイルを同時にインストールすることができます。

そのファイルを使用します。 そこにあるXNUMX文字のパリンドロームすべてを知りたいと思っていることがわかりました。 知らない人のために:回文はcapicúaの単語です。つまり、左から右へ、そして右から左へと読むことができます。 次のコマンドを試してみましょう。

grep '^\(.\)\(.\)\(.\).\3\2\1$' /usr/share/dict/words

少し変に見えますよね? 試してみると、結果はディストリビューションの言語とリストにある単語によって異なりますが、私の場合、スペイン語の場合、結果は次のようになります。

アニリンアニリンローリング

この正規表現がどのように機能するかを見てみましょう。

すでにわかっている「^」と「$」を除いて、左側に最初に表示されるのは、括弧で囲まれたXNUMXつのドットグループです。 各括弧の前にあるバーと混同しないでください。 基本的な正規表現を使用しているため、括弧をエスケープする必要がありますが、他の意味はありません。 重要なのは、ドットが付いたXNUMX文字を要求していることですが、これらのドットはそれぞれ括弧で囲まれています。 これは、これらのポイントに一致する文字を保存して、正規表現から再度参照できるようにするためです。 これは、後で交換を行う際に役立つ括弧のもうXNUMXつの使用法です。

これは、以下の1つの数字の前にスラッシュが付いている場所です。 この場合、バーが重要です。 以下の番号が後方参照であり、前の括弧の2つを参照していることを示すために使用されます。 例:\ XNUMXは最初の括弧を示し、\ XNUMXはXNUMX番目の括弧を示します。

つまり、私たちが入力した正規表現では、探しているのは、任意のXNUMX文字で始まり、XNUMX番目と同じ文字、XNUMX番目と同じ文字、および別の文字を持つすべての単語です。それは最初と同じです。 結果は、単語リストにあるXNUMX文字の回文です。 私たちが望んでいたように。

拡張正規表現を使用している場合、括弧をエスケープする必要はありませんが、拡張正規表現では、標準化されていないため、すべてのプログラムで後方参照が機能するとは限りません。 ただし、grepを使用すると機能するため、同じことを行う別の方法になる可能性があります。 必要に応じて試すことができます。

置換式:sedコマンド

検索に加えて、正規表現の最良の使用法のXNUMXつは、複雑なテキストを置き換えることです。 これを行うには、sedコマンドを使用する方法があります。 sedコマンドの威力は、テキストの置き換えをはるかに超えていますが、ここではそのために使用します。 このコマンドで使用する構文は次のとおりです。

sed [-r] 's/REGEX/REPL/g' FICHERO

または:

COMANDO | sed [-r] 's/REGEX/REPL/g'

ここで、REGEXは検索正規表現であり、REPLは置換正規表現です。 このコマンドは、指定したファイル内の何も実際には置き換えないことに注意してください。ただし、このコマンドは、ターミナルでの置き換えの結果を表示するため、次に配置するコマンドに怖がらないでください。 それらのいずれも、システム上のファイルを変更することはありません。

簡単な例から始めましょう。 / etcディレクトリには、通常「#」で始まるコメントが含まれるさまざまな構成ファイルがあります。 コメントなしでこれらのファイルのXNUMXつを見たいとしましょう。 たとえば、fstabを使用して実行します。 あなたが望むもので試すことができます。

sed 's/#.*//g' /etc/fstab

fstabに何があるかによって異なるため、ここではコマンドの結果を示しませんが、コマンドの出力をファイルの内容と比較すると、すべてのコメントが消えていることがわかります。

このコマンドでは、検索式は«です。#.*"、それは"# "の後に任意の数の文字、つまりコメントが続きます。 そして、置換式では、XNUMXつのバーを続けて見ると、何もないことがわかります。したがって、コメントを何も置き換えない、つまりコメントを削除します。 より単純な不可能。

今度は反対のことをします。 ファイルのすべての行にコメントすることが必要だとします。 このように試してみましょう:

sed 's/^/# /g' /etc/fstab

コマンドの出力では、すべての行がハッシュマークと空白スペースで始まっていることがわかります。 私たちが行ったことは、行の先頭を«に置き換えることです# «。 これも、置き換えられるテキストが常に同じである非常に単純な例ですが、ここでもう少し複雑にします。

置換の利点は、置換式で、前に説明したような後方参照を使用できることです。 記事の冒頭でダウンロードしたフレーズファイルに戻りましょう。 括弧内にあるすべての大文字を入力しますが、次のコマンドを使用して実行します。

sed 's/\([A-Z]\)/(\1)/g' frases

ここにあるのは、検索式の括弧を参照する置換式の後方参照です。 置換式の括弧は通常の括弧です。 置換表現では、特別な意味はなく、そのまま入れられます。 その結果、すべての大文字は、それが何であれ、括弧で囲まれた同じ文字に置き換えられます。

置換式でも使用できる別の文字があります。これは「&」であり、検索式に一致するすべてのテキストに置き換えられます。 この例としては、ファイル内のすべてのフレーズを引用符で囲む場合があります。 これは、次のコマンドで実行できます。

sed 's/.*/"&"/g' frases

このコマンドの操作は前のコマンドと非常に似ていますが、ここで置き換えるのは、行全体を引用符で囲んだ同じ行に変更することだけです。 「&」を使用しているため、括弧を付ける必要はありません。

正規表現を使用したいくつかの便利なコマンド

ここに、私が便利または好奇心が強く、正規表現を使用するいくつかのコマンドがあります。 これらのコマンドを使用すると、正規表現の有用性はこれまでに示した例よりもはるかに優れていますが、正規表現を理解するには、正規表現がどのように機能するかを説明することが重要であるように思われました。

  • manページのセクションを表示する:

man bash | grep '^[A-Z][A-Z ]*$'

もちろん、bashコマンドは好きなように変更できます。 そして、人間からは、もちろん正規表現を使用して、興味のあるセクションに直接移動できます。 «/»を押して検索を開始し、«を書き込みます^ALIASES$»たとえば、ALIASESセクションに移動します。 数年前に正規表現を使い始めたのはこれが初めてだと思います。 マニュアルのいくつかのページを移動することは、このようなトリックなしではほとんど不可能です。

  • 特別なユーザーを含む、マシンのすべてのユーザーの名前を表示します。

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

  • ユーザー名を表示しますが、シェルを持つユーザー名のみを表示します。

grep -vE '(/false|/nologin)$' /etc/passwd | sed 's/\([^:]*\).*/\1/g'

実際には単一の正規表現で実行できますが、その方法はこれらの記事で説明したことを超えているため、XNUMXつのコマンドを組み合わせて実行しました。

  • 数値ファイルのすべての数値の最後のXNUMX桁の前にコンマを挿入します。

sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers

6桁までの数字でのみ機能しますが、XNUMX桁の他のグループに区切り文字を配置するために、複数回呼び出すことができます。

  •  ファイルからすべての電子メールアドレスを抽出します。

grep -E '\<[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\>' FICHERO

  • ファイルに表示されるすべての日付の日、月、年を区切ります。

sed -r 's/([0-9]{2})[/-]([0-9]{2})[/-]([0-9]{4})/Día: \1, Mes: \2, Año: \3/g' FICHERO

  • ローカルIPを確認してください:

/sbin/ifconfig | grep 'inet .*broadcast' | sed -r 's/[^0-9]*(([0-9]+\.){3}[0-9]+).*/\1/g'

これは単一のsedコマンドでも実行できますが、簡単にするためにgrepとsedに分ける方がよいでしょう。

いくつかの便利なアドレス

正規表現に関連して役立つ可能性のあるアドレスを次に示します。

  • 正規表現ライブラリ:これは、興味のあるトピックに関連する正規表現を検索できる正規表現ライブラリです。 Webアドレス、IDなどを検索します。
  • RegExr:オンライン正規表現チェッカー。 テキストを入力し、検索または置換のいずれかで正規表現を適用できます。 正規表現に関する情報を提供し、その動作を変更するためのいくつかのオプションがあります。
  • 正規表現テスター:ブラウザから正規表現をチェックできるFirefoxのアドオンです。

結論

今のところそれだけです。 正規表現は複雑ですが便利です。 それらを学ぶには時間がかかりますが、あなたが私のようであれば、それらで遊ぶのは楽しいように思え、少しずつそれらを習得します。 それは全世界です。 怠惰な数量詞、PERLスタイルの正規表現、マルチラインなどについては、まだ言うことがたくさんあります。 そして、各プログラムにはその特性とバリアントがあるため、新しいプログラムで正規表現を作成する必要があるたびに、使用しているプログラムのドキュメントを常に確認することをお勧めします。

ねえ! …やあ! … 目を覚ます! …あなたは何をしているのですか? 🙂

ソース

私がここから取ったこの記事の正規表現のアイデアと例のいくつか:


記事の内容は、次の原則に準拠しています。 編集倫理。 エラーを報告するには、 ここで.

15コメント、あなたのコメントを残してください

コメントを残す

あなたのメールアドレスが公開されることはありません。 必須フィールドには付いています *

*

*

  1. データの責任者:MiguelÁngelGatón
  2. データの目的:SPAMの制御、コメント管理。
  3. 正当化:あなたの同意
  4. データの伝達:法的義務がある場合を除き、データが第三者に伝達されることはありません。
  5. データストレージ:Occentus Networks(EU)がホストするデータベース
  6. 権利:いつでも情報を制限、回復、削除できます。

  1.   エラヴ

    マスター!!!

    1.    ヘクスボーグ

      それほど悪くはありませんが、どうもありがとうございました。 人々がそれを好きになることを願っています。 🙂

      1.    オスカー

        私はそれが好きです!

        1.    ヘクスボーグ

          それなら私は何か正しいことをしたに違いない。 笑!! 🙂

          コメントありがとうございます。

          1.    ブレアパスカル

            男を書き続けて、それを続けてください。

          2.    ヘクスボーグ

            @ブレーズパスカル:あなたのようなコメントはそれを奨励します。 🙂ありがとうございました!!

      2.    シトゥクス

        私もそれが好きでした...ありがとう🙂

        1.    ヘクスボーグ

          コメントありがとうございます。 もう少し書きたいと思います。 🙂

  2.   マリアン

    あなたの投稿は素晴らしく、たくさんのことを学びます。むしろ、エレガントで効率的な方法でタスクを実行することを学びます。

    シェルスクリプトの投稿をすべて収集することを考えましたか? PDFに分類すると、優れたマニュアルになります。

    元気を出して、ありがとうございました!

    1.    ヘクスボーグ

      どうもありがとう!! それは悪い考えではありません。 現時点ではXNUMXつしかありませんが、後で考えます。 🙂

  3.   キヨフ

    非常に良い記事、5 +。

    1.    ヘクスボーグ

      ありがとうございました。 私はあなたがそれを好きうれしい。 🙂

  4.   セバスチャン

    優秀な! 次の式を変更する必要がありますが、その方法がわかりません。
    192.168.0.138 / Server by 192.168.0.111 / data
    問題は「/」記号にあります。
    私は次のコマンドを使用しています:
    見つける。 -name "* .txt" -exec sed -i's / TEXT1 / TEXT2 / g '{} \;
    この種のタスクを寛容に実行するために使用されるものですが、私はできません...
    誰かが私がそれをどのようにすべきか知っていますか?
    ハグ!
    セバ

    1.    ヘクスボーグ

      あなたがしなければならないことはこのようにキャラクターをエスケープすることです:

      見つける。 -name "* .txt" -exec sed -i's / \ / Server / \ / data / g '{} \;

      sedで別の区切り文字を使用することもできます。 それはバーである必要はありません。 Sedでは、任意の文字を使用できます。 たとえば、これはより明確になります。

      見つける。 -name "* .txt" -exec sed -i's | / Server | / data | g '{} \;

      また、このコメントからコマンドをコピーして貼り付ける場合は、引用符に注意してください。ワードプレスがそれらを活版印刷のものに変更します。 🙂

      ご挨拶。

  5.   セバスチャン

    優秀!!!!
    私は長い間この解決策を探していました。
    ここで、使用した完全なコマンドを残します

    見つける。 -name "* .txt" -exec sed -i's | 192 \ .168 \ .0 \ .238 \ /サーバー| 192 \ .168 \ .0 \ .111 \ / data | g '{} \;

    このコマンドの利点は、すべての.txtファイル(または必要な拡張子)を再帰的に変更することです...非常に注意する必要があります。
    しかし、それは非常に便利です!!!

    さて、すべてに感謝し、グループ全体に千のお祝いを。
    いつもメールで読んでいます!
    抱擁
    セバ