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

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

正規表現は、文字のいくつかのシーケンスを記述するために使用できる文字列です。正規表現は、次のようないくつかの異なるUnixコマンドで使用されます。edsedawkgrep、およびより限定された範囲で、 vi

ここに SED を意味する stream editor。このストリーム指向のエディターは、スクリプトを実行するためだけに作成されました。したがって、入力したすべての入力は通過してSTDOUTに送られ、入力ファイルは変更されません。

sedを呼び出す

始める前に、ローカルコピーがあることを確認しましょう /etc/passwd 使用するテキストファイル sed

前述のように、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/passwdsedパイプを通ってsedのパターンスペースに入る。パターンスペースは、sedが操作に使用する内部作業バッファーです。

sedの一般的な構文

以下はsed−の一般的な構文です。

/pattern/action

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

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

シニア番号 範囲と説明
1

p

行を印刷します

2

d

行を削除します

3

s/pattern1/pattern2/

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

sedですべての行を削除する

これで、sedを使用してすべての行を削除する方法を理解できます。sedを再度呼び出します。しかし、sedは現在、editing command delete line、一文字で示されます d

$ 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
$

番号1が前に追加されていることに注意してください delete editコマンド。これは、ファイルの最初の行で編集コマンドを実行するようにsedに指示します。この例では、sedはの最初の行を削除します/etc/password ファイルの残りの部分を印刷します。

sedのアドレス範囲

これで、操作方法を理解できます the sed address ranges。では、ファイルから複数の行を削除したい場合はどうでしょうか。次のように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行が削除されます。

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

シニア番号 範囲と説明
1

'4,10d'

4から始まる行目の10まで番目に削除されます

2

'10,4d'

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

3

'4,+5d'

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

4

'2,5!d'

これは、2から始まる以外のすべてを削除ND 5まで番目の行

5

'1~3d'

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

6

'2~2d'

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

7

'4,10p'

4番目から10番目までの行が印刷されます

8

'4,d'

これにより構文エラーが発生します

9

',10d'

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

Note −使用中 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 フラグを立てると、一度に複数を指定できます。

シニア番号 フラグと説明
1

g

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

2

NUMBER

NUMBER番目の一致のみを置き換えます

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

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

空のスペースとの交換

空の置換文字列を使用して、ルート文字列をから削除します /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行には文字列が含まれていました sh に変更されました quiet、しかし、残りの行はそのまま残されました。

マッチングコマンド

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

$ 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

正規表現の使用

パターンを照合しながら、より柔軟性のある正規表現を使用できます。

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

$ 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つの特殊文字を示します。

シニア番号 キャラクターと説明
1

^

行の先頭に一致します

2

$

行末に一致します

3

.

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

4

*

前の文字の0回以上の出現に一致します

5

[chars]

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

一致する文字

の使用法を示すために、さらにいくつかの式を見てください metacharacters。たとえば、次のパターン-

シニア番号 表現と説明
1

/a.c/

次のような文字列を含む行に一致します a+ca-cabcmatch、および a3c

2

/a*c/

次のような文字列と同じ文字列に一致します aceyacc、および arctic

3

/[tT]he/

文字列に一致します The そして the

4

/^$/

空白行に一致

5

/^.*$/

それが何であれ、行全体に一致します

6

/ */

1つ以上のスペースに一致します

7

/^$/

マッチス blank

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

シニア番号 セットと説明
1

[a-z]

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

2

[A-Z]

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

3

[a-zA-Z]

1文字に一致

4

[0-9]

単一の番号に一致します

5

[a-zA-Z0-9]

1つの文字または数字に一致します

文字クラスキーワード

いくつかの特別なキーワードは一般的に利用可能です regexps、特に採用しているGNUユーティリティ regexps。これらは、物事を単純化し、読みやすさを向上させるため、sed正規表現に非常に役立ちます。

たとえば、文字 a through z とキャラクター A through Z、キーワードを持つそのような文字クラスの1つを構成します [[:alpha:]]

このコマンドは、英字クラスキーワードを使用して、次の行のみを出力します。 /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

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

シニア番号 キャラクタークラスと説明
1

[[:alnum:]]

英数字[azAZ 0-9]

2

[[:alpha:]]

アルファベット[azAZ]

3

[[:blank:]]

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

4

[[:cntrl:]]

制御文字

5

[[:digit:]]

数字[0-9]

6

[[:graph:]]

表示されている文字(空白を除く)

7

[[:lower:]]

小文字[az]

8

[[:print:]]

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

9

[[:punct:]]

句読文字

10

[[:space:]]

空白

11

[[:upper:]]

大文字[AZ]

12

[[:xdigit:]]

16進数[0-9af AF]

Aampersand参照

ザ・ sed metacharacter &一致したパターンの内容を表します。たとえば、というファイルがあるとしますphone.txt 次のような電話番号でいっぱい-

5555551212
5555551213
5555551214
6665551215
6665551216
7775551217

あなたは作りたい area code(最初の3桁)読みやすくするために括弧で囲みます。これを行うには、アンパサンド置換文字を使用できます-

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

(666)5551216
(777)5551217

ここでパターン部分では、最初の3桁を照合してから、 & あなたはそれらの3桁を周囲に置き換えています parentheses

複数のsedコマンドの使用

次のように、1つのsedコマンドで複数のsedコマンドを使用できます。

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

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

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

$ 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

Note −上記の例では、文字クラスのキーワードを繰り返す代わりに [[:digit:]] 3回、交換しました \{3\}、これは、先行する正規表現が3回一致することを意味します。私達はまた使用しました\ 改行を付けるには、コマンドを実行する前にこれを削除する必要があります。

バックリファレンス

ザ・ ampersand metacharacterは便利ですが、さらに便利なのは、正規表現で特定の領域を定義する機能です。これらの特別な領域は、置換文字列の参照として使用できます。正規表現の特定の部分を定義することにより、特別な参照文字を使用してそれらの部分を参照することができます。

するために back references、最初にリージョンを定義してから、そのリージョンを参照する必要があります。地域を定義するには、backslashed parentheses関心のある各領域の周り。次に、円記号で囲む最初の領域は、によって参照されます。\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

Note −上記の例では、括弧内の各正規表現は次のように逆参照されます。 \1\2等々。使用しました\ここで改行します。これは、コマンドを実行する前に削除する必要があります。