Unix-regular-expressions

提供:Dev Guides
移動先:案内検索

Unix/Linux-SEDを使用した正規表現

この章では、UnixのSEDを使用した正規表現について詳しく説明します。

正規表現は、複数の文字シーケンスを記述するために使用できる文字列です。 正規表現は、 edsedawkgrep 、さらに限定された範囲の vi など、さまざまなUnixコマンドで使用されます。

ここで、 SED は* s tream ed * itorを表します。 このストリーム指向のエディターは、スクリプトの実行専用に作成されました。 したがって、そこに入力するすべての入力は通過してSTDOUTに送られ、入力ファイルは変更されません。

sedの呼び出し

開始する前に、 sed で動作する /etc/passwd テキストファイルのローカルコピーがあることを確認してください。

前述のように、sedは次のようにパイプを介してデータを送信することで呼び出すことができます-

$ cat/etc/passwd | sed
Usage: sed [OPTION]... {script-other-script} [input-file]...

  -n, --quiet, --silent
                 suppress automatic printing of pattern space
  -e script, --expression = script
...............................
*cat* コマンドは、パイプを介して */etc/passwd* の内容を *sed* にダンプし、sedのパターンスペースに入れます。 パターン空間は、sedがその操作に使用する内部作業バッファーです。

sedの一般的な構文

sedの一般的な構文は次のとおりです-

/pattern/action

ここで、 pattern は正規表現であり、 action は次の表に示すコマンドの1つです。 pattern が省略された場合、上で見たように action がすべての行に対して実行されます。

パターンを囲むスラッシュ文字(/)は、区切り文字として使用されるため必要です。

Sr.No. Range & Description
1

p

行を印刷します

2

d

行を削除します

3

s/pattern1/pattern2/

pattern1の最初の出現をpattern2に置き換えます

sedを使用してすべての行を削除する

これで、sedを使用してすべての行を削除する方法を理解できます。 sedを再度呼び出します。しかし、sedは現在、単一の文字 d で示される editingコマンドdelete line を使用することになっています-

$ cat/etc/passwd | sed 'd'
$

次の例のように、パイプを介してファイルを送信してsedを呼び出す代わりに、sedにファイルからデータを読み取るように指示することができます。

次のコマンドは、catコマンドなしで、前の例とまったく同じことを行います-

$ sed -e 'd'/etc/passwd
$

sedアドレス

sedはアドレスもサポートしています。 アドレスは、ファイル内の特定の場所、または特定の編集コマンドを適用する範囲です。 sedはアドレスを検出しないと、ファイル内のすべての行で操作を実行します。

次のコマンドは、使用しているsedコマンドに基本アドレスを追加します-

$ cat/etc/passwd | sed '1d' |more
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
$
*delete edit* コマンドの前に番号1が追加されていることに注意してください。 これは、ファイルの最初の行で編集コマンドを実行するようにsedに指示します。 この例では、sedは */etc/password* の最初の行を削除し、ファイルの残りを印刷します。

sedアドレス範囲

これで、* sedアドレス範囲*の操作方法を理解できます。 では、ファイルから複数の行を削除したい場合はどうでしょうか? 次のようにsedでアドレス範囲を指定できます-

$ cat/etc/passwd | sed '1, 5d' |more
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
$

上記のコマンドは、1から5までのすべての行に適用されます。 これにより、最初の5行が削除されます。

次のアドレス範囲を試してください-

Sr.No. Range & Description
1

'4,10d'

4番目から10番目までの行は削除されます

2

'10,4d'

sedは逆方向に機能しないため、10 ^ th ^行のみが削除されます

3

'4,PLUS5d'

これはファイルの4行目と一致し、その行を削除し、次の5行を削除し続け、削除を中止して残りを出力します

4

'2,5!d'

これは、2 ^ nd ^から5 ^ th ^行までを除くすべてを削除します

5

'1~3d'

これにより、最初の行が削除され、次の3行がステップオーバーされ、4行目が削除されます。 Sedは、ファイルの終わりまでこのパターンを適用し続けます。

6

'2~2d'

これにより、sedは2行目を削除し、次の行をステップオーバーし、次の行を削除し、ファイルの終わりに達するまで繰り返します。

7

'4,10p'

4 ^ th ^から10 ^ th ^までの行が印刷されます

8

'4,d'

これにより、構文エラーが生成されます

9

',10d'

これも構文エラーを生成します

注意- p アクションを使用しているときは、*-n *オプションを使用して、行の印刷が繰り返されないようにする必要があります。 次の2つのコマンドの違いを確認してください-

$ cat/etc/passwd | sed -n '1,3p'
Check the above command without -n as follows −
$ cat/etc/passwd | sed '1,3p'

置換コマンド

*s* で示される置換コマンドは、指定した文字列を指定した他の文字列で置換します。

ある文字列を別の文字列に置き換えるには、sedに最初の文字列が終了し、置換文字列が始まる場所に関する情報が必要です。 このため、2つの文字列をスラッシュ( / )文字でブックエンドします。

次のコマンドは、文字列 root の行で最初に出現するものを文字列 amrood に置き換えます。

$ cat/etc/passwd | sed 's/root/amrood/'
amrood:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
..........................

sedは行の最初の出現のみを置換することに注意することが非常に重要です。 文字列ルートが1行に複数回出現する場合、最初に一致したものだけが置き換えられます。

sedがグローバル置換を実行するには、次のようにコマンドの末尾に文字 g を追加します-

$ cat/etc/passwd | sed 's/root/amrood/g'
amrood:x:0:0:amrood user:/amrood:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
...........................

置換フラグ

*g* フラグに加えて渡すことができるその他の便利なフラグがいくつかあり、一度に複数のフラグを指定できます。
Sr.No. Flag & Description
1

g

最初の一致だけでなく、すべての一致を置き換えます

2

NUMBER

NUMBER ^ th ^マッチのみを置換します

3

p

置換が行われた場合、パターンスペースを出力します

4

w FILENAME

置換が行われた場合、結果をFILENAMEに書き込みます

5

I or i

大文字と小文字を区別しない方法で一致

6

M or m

特殊な正規表現文字および$の通常の動作に加えて、このフラグにより​​、は改行の後の空の文字列に一致し、$は改行の前の空の文字列に一致します

代替文字列セパレーターの使用

スラッシュ文字を含む文字列を置換する必要があるとします。 この場合、 s の後に指定された文字を指定することにより、異なるセパレーターを指定できます。

$ cat/etc/passwd | sed 's:/root:/amrood:g'
amrood:x:0:0:amrood user:/amrood:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh

上記の例では、単純なルートではなく /root を検索しようとしたため、スラッシュ:の代わりに*:を *delimiter として使用しました。

空のスペースで置き換える

空の置換文字列を使用して、ルート文字列を /etc/passwd ファイルから完全に削除します-

$ cat/etc/passwd | sed 's/root//g'
:x:0:0::/:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh

アドレス置換

あなたが文字列 sh を文字列 quiet で10行目のみで置換したい場合は、次のように指定できます-

$ cat/etc/passwd | sed '10s/sh/quiet/g'
root:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/quiet

同様に、アドレス範囲の置換を行うには、次のようなことを行うことができます-

$ cat/etc/passwd | sed '1,5s/sh/quiet/g'
root:x:0:0:root user:/root:/bin/quiet
daemon:x:1:1:daemon:/usr/sbin:/bin/quiet
bin:x:2:2:bin:/bin:/bin/quiet
sys:x:3:3:sys:/dev:/bin/quiet
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh

出力からわかるように、最初の5行では文字列 shquiet に変更されましたが、残りの行は変更されていません。

マッチングコマンド

あなたは、次のようにすべての一致する行を印刷する*-n オプションと一緒に *p オプションを使用します-

$ cat testing | sed -n '/root/p'
root:x:0:0:root user:/root:/bin/sh
[root@ip-72-167-112-17 amrood]# vi testing
root:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh

正規表現を使用する

パターンの照合中に、より柔軟な正規表現を使用できます。

_daemon_で始まるすべての行に一致し、それらを削除する次の例を確認してください-

$ cat testing | sed '/^daemon/d'
root:x:0:0:root user:/root:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh

以下は、 sh で終わるすべての行を削除する例です-

$ cat testing | sed '/sh$/d'
sync:x:4:65534:sync:/bin:/bin/sync

次の表に、正規表現で非常に役立つ4つの特殊文字を示します。

Sr.No. Character & Description
1

^

行頭と一致します

2

$

行末に一致します

3

.

任意の1文字と一致します

4 前の文字のゼロ回以上の出現に一致します
5

[chars]

charsで指定された文字のいずれかに一致します。charsは文字のシーケンスです。 文字の範囲を示すために-文字を使用できます。

一致する文字

  • メタ文字*の使用を示すために、さらにいくつかの式を見てください。 たとえば、次のパターン-
Sr.No. Expression & Description
1

/a.c/

  • a+ c* 、 *a-c* 、 *abc* 、 *match* 、 *a3c* などの文字列を含む行に一致します
2

/a*c/

  • ace* 、 *yacc* 、 *arctic* などの文字列と同じ文字列に一致します
3

/[tT]he/

ストリング The および the に一致します

4

/^$/

空白行に一致

5

/^.$/*

行全体に一致します

6

//*

1つ以上のスペースに一致

7

/^$/

  • 空白*行に一致

次の表は、頻繁に使用される文字セットを示しています-

Sr.No. Set & Description
1

[a-z]

単一の小文字と一致します

2

[A-Z]

単一の大文字と一致します

3

[a-zA-Z]

単一の文字と一致します

4

[0-9]

単一の数字と一致します

5

[a-zA-Z0-9]

単一の文字または数字と一致します

文字クラスのキーワード

いくつかの特別なキーワード、特に regexps を使用するGNUユーティリティは、一般的に regexps で利用できます。 これらは物事を簡素化し、読みやすさを高めるため、sed正規表現に非常に役立ちます。

たとえば、文字 aからz および文字 AからZ は、キーワード :alpha: を持つ文字の1つのクラスを構成します。

アルファベット文字クラスキーワードを使用して、このコマンドは、アルファベットの文字で始まる /etc/syslog.conf ファイル内の行のみを印刷します-

$ cat/etc/syslog.conf | sed -n '/^[[:alpha:]]/p'
authpriv.*                        /var/log/secure
mail.*                             -/var/log/maillog
cron.*                            /var/log/cron
uucp,news.crit                    /var/log/spooler
local7. */var/log/boot.log

次の表は、GNU sedで使用可能な文字クラスキーワードの完全なリストです。

Sr.No. Character Class & Description
1
  • *

英数字[a-z A-Z 0-9]

2

'

アルファベット[a-z A-Z]

3

'

空白文字(スペースまたはタブ)

4

'

制御文字

5

'

数字[0-9]

6

'

可視文字(空白を除く)

7

'

小文字[a-z]

8

'

印刷可能文字(非制御文字)

9

'

句読文字

10

'

空白

11

'

大文字[A-Z]

12

'

16進数[0-9 a-f A-F]

アンパサンド参照

  • sedメタ文字&は、一致したパターンの内容を表します。 たとえば、次のような電話番号でいっぱいの *phone.txt というファイルがあるとします-
5555551212
5555551213
5555551214
6665551215
6665551216
7775551217

読みやすいように、括弧で囲まれた*市外局番*(最初の3桁)を作成します。 これを行うには、アンパサンド置換文字を使用できます-

$ sed -e 's/^[[:digit:]][[:digit:]][[:digit:]]/(&)/g' phone.txt
(555)5551212
(555)5551213
(555)5551214
(666)5551215

(666)5551216
(777)5551217

ここで、パターン部分では、最初の3桁を照合し、*&*を使用して、これらの3桁を周囲の*括弧*に置き換えています。

複数のsedコマンドの使用

次のように、単一のsedコマンドで複数のsedコマンドを使用できます-

$ sed -e 'command1' -e 'command2' ... -e 'commandN' files

ここで、 command1 から commandN は、前述のタイプのsedコマンドです。 これらのコマンドは、filesによって指定されたファイルのリスト内の各行に適用されます。

同じメカニズムを使用して、次のように上記の電話番号の例を書くことができます-

$ sed -e 's/^[[:digit:]]\{3\}/(&)/g'  \
   -e 's/)[[:digit:]]\{3\}/&-/g' phone.txt
(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(666)555-1216
(777)555-1217

-上記の例では、文字クラスのキーワード :digit: を3回繰り返す代わりに、 \\ {3 \} に置き換えました。つまり、前の正規表現が3回。 また、改行を使用するために \ を使用しましたが、これはコマンドを実行する前に削除する必要があります。

バックリファレンス

  • アンパサンドメタ文字*は便利ですが、さらに便利なのは、正規表現で特定の領域を定義できることです。 これらの特別な領域は、置換文字列の参照として使用できます。 正規表現の特定の部分を定義することにより、特別な参照文字を使用してそれらの部分を参照できます。

逆参照*を行うには、最初に領域を定義してから、その領域を参照し直す必要があります。 領域を定義するには、対象の各領域の周りに*バックスラッシュ付き括弧*を挿入します。 バックスラッシュで囲む最初の領域は *\ 1 で参照され、2番目の領域は \ 2 で参照されます。

*phone.txt* には次のテキストがあると仮定します-
(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(666)555-1216
(777)555-1217

次のコマンドを試してください-

$ cat phone.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/Area \
   code: \1 Second: \2 Third: \3/'
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214
Area code: (666) Second: 555- Third: 1215
Area code: (666) Second: 555- Third: 1216
Area code: (777) Second: 555- Third: 1217

注意-上記の例では、括弧内の各正規表現は \ 1\ 2 などによって後方参照されます。 ここで改行するために \ を使用しました。 これは、コマンドを実行する前に削除する必要があります。