【Linux】正規表現を駆使してsedコマンドで置換してみた

f:id:hira98:20190721171442p:plain

【結論】

  • 置換(ちかん)とは、あるものを他のものに置き換えること。(念の為)
  • Linuxではsedコマンドで文字列を置換できる。
  • 正規表現と組み合わせることで、汎用的な置換ができる。
  • 正規表現を使いこなせると、自分に酔うことができる。(個人の感想)

【目次】

はじめに

次のsedコマンドを実行すると

$ cat hoge.txt | sed 's/^.*href="\(.*\)">\(.*\)<.*$/\1,\2/'

以下のhoge.txtファイルを

<a class="entry-title-link" href="url1">ブログのタイトル1</a>
<a class="entry-title-link" href="url2">ブログのタイトル2</a>
<a class="entry-title-link" href="url3">ブログのタイトル3</a>

次のように置換することができます。

url1,ブログのタイトル1
url2,ブログのタイトル2
url3,ブログのタイトル3

なぜこのような置換が行えるかについてまとめました。

sedコマンドの書式

sedコマンドは文字列を置換するためのコマンドで、構文は以下になります。

$ sed 's/置換前の文字/置換後の文字/'

以下のファイル(fruit_list.txt)があったとします。

$ cat fruit_list.txt 
apple
banana
orange
lemon
melon

このうち、appleを大文字に置換して出力する場合は次のコマンドを実行します。

$ cat fruit_list.txt | sed 's/apple/APPLE/'
APPLE
banana
orange
lemon
melon
$ cat fruit_list.txt | sed "s/apple/APPLE/"

ちなみに、引数は'でなく"で囲むこともでき、使い分けのルールはPythonと同じです。

"を含む文字を置換する場合は'で囲み、'を含む文字を置換する場合は"で囲みます。

"'を含む文字を置換したい場合は、\"とか\'のように\エスケープしてあげればOKです。

sedコマンドを分解する

sedコマンド自体は大したことないのですが、汎用性を持たせるために正規表現を使おうとすると、一気にややこしくなります。

難解な呪文を理解するためには、分解して一つ一つ理解していけばいい。

と言う持論に従って、正規表現を使ったsedコマンドを分解したのが下図になります。

f:id:hira98:20190721170755p:plain

置換対象の文字

f:id:hira98:20190721170813p:plain

  • ^.*href="の解説
    • ^は文字の先頭を表します。
    • .任意のキャラクター文字表し、*は直前の正規表現の0回以上の繰り返しを表します。
    • よって、.*で任意の連続したキャラクタ文字を表します。
    • ^.*href="とすることで、先頭からhref="までの文字列を表しています。
  • \(.*\)">/(.*^)<の解説
  • 正規表現で一部の文字列を抜き出す場合、()で囲みます。
    • ただし、sedコマンドでは()特殊文字であるため、(\()\)のように\エスケープしてあげる必要があります。
    • ()での抜き出しは複数指定することができ、左から順に1,2,3...と数字が割り振られていきます。✨
  • <.*$の解説
  • $は文字列の末尾を表します。
    • <.*$と書くことで、<から末尾までの文字を表しています。

置換後の文字

f:id:hira98:20190721170826p:plain

置換対象の文字の説明で、✨()での抜き出しは複数指定することができ、左から順に1,2,3...と数字が割り振られていきます。✨と説明しました。

ここで割り振られた数字は、置換後の文字で\1\2と記述して指定することで任意のフォーマットに変換して置換することができます。

参考情報

正規表現メモ

sedでダブルクォーテーションの中にある文字列を抽出する - Qiita

置換 - Wikipedia

さいごに

前職では正規表現を使ってコードを書くことはなく、ログから特定の文字列を抜き出すのに知っていたら便利程度でしかありませんでした。よって、正規表現を使わずとも、エディタやエクセルの機能を活用すればなんとかできたので、正規表現は避けていました💦

しかし、現在の業務では正規表現を使ってロジックを組む機会が多々あるので仕方なく勉強していました😭

しかし最近は、一見すると意味不明な記号の羅列にしか見えない正規表現を使いこなせてきている自分に酔っている自分がいます😎