Unix / Linux – SEDによる正規表現

スポンサーリンク

本当にわからないとこがあった場合一人では解決できません。
『teratail』とはエンジニア特化型のQ&Aサイトです。 すべてのエンジニアさんが抱えている悩みを共有して 解決するための質問サイトです
無料なのでまずは登録して使ってみてください。メールアドレスだけで登録可能です ----------------------------------------------------------------------------------------

この章では、UNIXでのSEDの正規表現について詳しく説明します。

sedは与えられた文字列を,ルールに従って変換するコマンドです。文字列の置換,行の削除といった処理が行えるようになります。

 

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コマンドはもちろん修正のコマンドですよ。

sedの一般的な構文


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

/pattern/action

ここで、patternは正規表現であり、actionは次の表に示すコマンドの1つです。patternが省略された場合、上で見たように、行ごとにアクションが実行されます。

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

S.No. 範囲と説明
1 p

行を印刷します。

2 d

行を削除します。

3 s / pattern1 / pattern2 /

pattern1の最初のオカレンスをpattern2に置き換えます。

sedを使ってすべての行を削除する


sedを使ってすべての行を削除する方法を理解するようになりました。もう一度sedを呼び出します。sedは現在、編集コマンド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
$

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行が削除されます。

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

S.No. 範囲と説明
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までTHが印刷され

8 ‘4、d’

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

9 ‘、10d’

これはまた、構文エラーを生成するでしょう

 – pアクションの使用中は、-nオプションを使用して行印刷の繰り返しを避ける必要があります。次の2つのコマンドの違いを確認してください –

$ cat /etc/passwd | sed -n '1,3p'

-nを指定しないで上記のコマンドを次のようにチェックします。

$ 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は、行の最初のオカレンスだけを置換することに注意することが非常に重要です。文字列rootが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フラグに加えて他の有用なフラグもいくつか渡すことができ、一度に複数指定することができます。

S.No. フラグと説明
1 g

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

2

NUMBER 番目の試合のみを置き換えます

3 p

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

4 wファイル名

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

5 私または私

大文字と小文字を区別しないでマッチする

6 Mまたは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

上記の例では、使用しているとして区切り文字の代わりに、スラッシュ/私たちは、検索しようとしていたので、/ルートの代わりに、簡単なルートを。

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


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

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

住所置換


文字列shを10行目の文字列quietに置き換える場合は、次のように指定することができます。

$ 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がに変更静かな、しかし、行の残りはそのまま残っていました。

マッチングコマンド


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

正規表現の使用


パターンを照合する際に、柔軟性の高い正規表現を使用することができます。

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

S.No. キャラクターと説明
1 ^

行頭に一致します。

2 $

行末に一致します。

3

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

4 *

前の文字が0回以上出現したときに一致します。

5 [chars]

charsで指定された文字のいずれかに一致します。charsは文字の並びです。- 文字を使用して文字の範囲を指定することができます。

一致する文字


メタキャラクターの使用方法を示すために、さらにいくつかの表現を見てください。例えば、以下のパターン –

S.No. 式と説明
1 /交流/

a + cacabcmatcha3cなどの文字列を含む行に一致します。

2 /交流/

aceyaccarcticなどの文字列と同じ文字列に一致します。

3 / [tT] he /

文字列にマッチしますし、

4 / ^ $ /

空白行に一致します。

5 /^.*$/

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

6 / * /

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

7 / ^ $ /

空白行に一致します。

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

S.No. セット&説明
1 [az]

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

2 [AZ]

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

3 [a-zA-Z]

一文字にマッチする

4 [0-9]

単一の番号と一致します。

5 [a-zA-Z0-9]

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

文字クラスキーワード


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

たとえば、文字aからzおよび文字AからZは、キーワード[[: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

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

S.No. 文字クラスと説明
1 [[:alnum:]]

英数字[az AZ 0-9]

2 [[:アルファ:]]

アルファベット順[az AZ]

3 [[:ブランク:]]

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

4 [[:cntrl:]]

制御文字

5 [[:桁:]]

数字[0-9]

6 [[:グラフ:]]

可視文字(空白を除く)

7 [[:下:]]

小文字[az]

8 [[:印刷:]]

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

9 [[:punct:]]

句読点文字

10 [[:スペース:]]

空白

11 [[:アッパー:]]

大文字[AZ]

12 [[:xdigit:]]

16進数[0-9 AF AF]

Aampersand Referencing

 


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コマンドの使用


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

 – 上記の例では、文字クラスキーワード[[: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などで後ろから参照されます。ここで\を使用して改行しています。これは、コマンドを実行する前に削除する必要があります。

次のページ

 

スポンサーリンク

プログラミングは独学からは挫折の可能性が高いです。まずは無料体験ができる
コードキャンプが本当におすすめ。無料体験でわからないところを聞きましょう。
転職補助つき。カリキュラム終了後に転職紹介をしてくれます。