sed

シェルスクリプトは、『シェルスクリプト (英語: shell script) は、オペレーティングシステムのシェルまたはコマンドラインインタプリタ向けに書かれたスクリプト言語である。』です。

文字列を置換する

sedコマンドの基本的な使い方は、ファイル・標準出力の内容で文字列の置換を行うことです。

ファイルの内容を置換する

まずはsedコマンドにおいて最も基本的な使い方は、
ファイルの内容を置換するという使い方だ。

sed 's/置換前文字列/置換後文字列/g' ファイルPATH

※条件の最後に「g」を付けないと、”各行において最初に、マッチした箇所のみ”置換するので注意。

以下、sedコマンドでファイルの内容を置換する例

・「g」を付けないで置換

MacBook-Air-2:test_Dir root# sed 's/AAAA/aaaa/' test.txt

aaaaxxxAAAA  # 行中の最初にマッチしたAAAAだけ置換した
BBBBxxxBBBB
CCCCxxxCCCC
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

・「g」を付けて置換

MacBook-Air-2:test_Dir root# sed 's/AAAA/aaaa/g' test.txt

aaaaxxxaaaa  # マッチした全てのAAAAを置換した
BBBBxxxBBBB
CCCCxxxCCCC
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

置換の結果が異なることが確認できる。

※注意点として、sedコマンドを実行すると置換した内容が標準出力されるが、これはファイルの内容までは変更していない。置換内容でファイル保存まで行うには、後述する -i オプションを指定する必要がある。

標準出力の内容を置換する

sedコマンドは、ファイルの内容だけでなく、
標準出力の内容も置換することが可能だ。

標準出力 | sed 's/置換前文字列/置換後文字列/g'

以下、sedコマンドで標準出力の内容を置換する例

MacBook-Air-2:test_Dir root# cat test.txt | sed 's/AAAA/aaaa/g'
aaaaxxxaaaa
BBBBxxxBBBB
CCCCxxxCCCC
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

△行目にある特定の文字列を置換する場合

以下のように△に行数を指定することで、
△行目にある特定の文字列を置換するということが可能だ。

sed '△s/置換前文字列/置換後文字列/g'

以下、3行目の特定の文字列を置換する例

MacBook-Air-2:test_Dir root# sed '3s/xxx/ZZZ/' test.txt

AAAAxxxAAAA
BBBBxxxBBBB
CCCCZZZCCCC # 3行目のxxxをZZZに置換した
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

◯行目~◯行目にある特定の文字列を置換する場合

○行目~○行目までを置換する場合は、
以下のように開始行と終了行をカンマで区切って記述してやると良い。

sed '○,○s/置換前文字列/置換後文字列/g'

以下、5行目から6行目の特定の文字列を置換する例

MacBook-Air-2:test_Dir root# sed '5,6s/yyy/ZZZ/' test.txt
AAAAxxxAAAA
BBBBxxxBBBB
CCCCxxxCCCC
DDDDyyyDDDD
EEEEZZZEEEE  # 置換された
FFFFZZZFFFF  # 置換された

特定の文字列を含む行のみ置換する場合

特定の文字列(正規表現可)を含む行に対してのみ、置換することも出来る。

sed '/検索文字列/s/置換前文字列/置換後文字列/g'

以下、CCCCがある行の、xxxをZZZに置換する例

MacBook-Air-2:test_Dir root# sed '/CCCC/s/xxx/ZZZ/' test.txt
AAAAxxxAAAA
BBBBxxxBBBB
CCCCZZZCCCC # CCCCがある行の、xxxをZZZに置換した
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

行を挿入する

sedコマンドでは、特定の行に対して指定した行を挿入することも可能だ。
その際、実行する処理に応じて「i」と「a」を使い分けるのがポイントとなってくる。

※macOSで行挿入のsedコマンドを使用した場合、「extra characters after~」というエラーが出てしまい、正常に置換が行われない可能性がある。

指定した行番号の箇所に行を挿入する

以下のようにコマンドを実行することで、
◯行目の前に指定した行を挿入をすることが出来る。

sed '◯i 行'
[root@centos7 ~]# sed '4i testline' test.txt

AAAAxxxAAAA
BBBBxxxBBBB
CCCCxxxCCCC
testline         # 4行目の前に行を追加
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

指定した行の後ろに行を挿入する

以下のようにコマンドを実行することで、
◯行目の後ろに指定した行を挿入することが出来る。

sed '◯a 行'
[root@centos7 ~]# sed '4i testline' test.txt

AAAAxxxAAAA
BBBBxxxBBBB
CCCCxxxCCCC
DDDDyyyDDDD
testline # 4行目の後ろに行を追加
EEEEyyyEEEE
FFFFyyyFFFF

指定した複数の各行の前/後ろに行を挿入する

指定した行の範囲に対し、挿入を行う事も出来る。

sed '◯,◯i 挿入する行' #前に挿入する場合
sed '◯,◯a 挿入する行' #後に挿入する場合

1〜3行目の範囲で、行の前に行を挿入する例

[root@centos7 ~]# sed '1,3i testline' test.txt

testline # 1行目の前に行を追加
AAAAxxxAAAA
testline # 2行目の前に行を追加
BBBBxxxBBBB
testline # 3行目の前に行を追加
CCCCxxxCCCC
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

1〜3行目の範囲で、行の後ろに行を挿入する例

[root@centos7 ~]# sed '1,3a testline' test.txt

AAAAxxxAAAA
testline # 1行目の後ろに行を追加
BBBBxxxBBBB
testline # 2行目の後ろに行を追加
CCCCxxxCCCC
testline # 3行目の後ろに行を追加
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

指定したキーワードを持つ行の前・後に行を挿入する

キーワードを指定して、キーワードを含む行の前・後に行を挿入することも出来る。

sed '/キーワード/i 挿入する行' #前に挿入する場合
sed '/キーワード/a 挿入する行' #後に挿入する場合Copy

xxxというキーワードを含む行の前に、行を挿入する例

[root@centos7 ~]# sed '/xxx/i testline' test.txt

testline # 行を追加
AAAAxxxAAAA
testline # 行を追加
BBBBxxxBBBB
testline # 行を追加
CCCCxxxCCCC
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

xxxというキーワードを含む行の後ろに、行を挿入する例

[root@centos7 ~]# sed '/xxx/a testline' test.txt

AAAAxxxAAAA
testline # 行を追加
BBBBxxxBBBB
testline # 行を追加
CCCCxxxCCCC
testline # 行を追加
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

行を削除する

sedコマンドでは、
指定した行を削除して表示させることも可能だ。

◯行目を削除する

◯行目を削除する場合、以下のようにコマンドを実行する。

sed '○d'

以下4行目を削除する例

MacBook-Air-2:test_Dir root# sed '4d' test.txt

AAAAxxxAAAA
BBBBxxxBBBB
CCCCxxxCCCC
(4行目が消えて表示される)
EEEEyyyEEEE
FFFFyyyFFFF

◯行目~◯行目を削除する

◯行目~◯行目を削除する場合は、以下のようにする。

sed '◯,◯d'

以下1~4行目を削除する例

MacBook-Air-2:test_Dir root# sed '1,4d' test.txt

EEEEyyyEEEE
FFFFyyyFFFF

特定のキーワードを持つ行を削除する

特定のキーワードを持つ行を削除する場合は、以下のようにする。

sed '/キーワード/d'

以下、xxxというキーワードを持つ行を削除する例

MacBook-Air-2:test_Dir root# sed '/xxx/d' test.txt

DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

行の内容を上書きする

sedコマンドでは、
指定した行の内容を置換ではなく、上書きすることも可能だ。

※macOSで行上書きのsedコマンドを使用した場合、「command c expects \ followed by~」というエラーが出てしまい、正常に置換が行われない可能性がある。

◯行目の内容を上書きする

以下のようにコマンドを実行することで、
指定した行の内容を上書きして置き換える事が出来る。

sed '◯c 置き換え後の行'

以下4行目を上書きする例

MacBook-Air-2:test_Dir root# sed '4c testline' test.txt

AAAAxxxAAAA
BBBBxxxBBBB
CCCCxxxCCCC
testline      # 4行目が上書きされた
EEEEyyyEEEE
FFFFyyyFFFF

特定のキーワードを持つ行を上書きする

特定のキーワードを持つ行を上書きすることも出来る。

sed '/キーワード/c 置き換え後の行'

以下、yyyというキーワードを持つ行を上書きする例

MacBook-Air-2:test_Dir root# sed '/yyy/c testline' test.txt

AAAAxxxAAAA
BBBBxxxBBBB
CCCCxxxCCCC
testline      # 上書きされた
testline      # 上書きされた
testline      # 上書きされた

実行結果をファイルの内容に保存する

sedコマンドでは、前述した通り、実行後の内容を標準出力するだけであり、
ファイルの内容までは変更して保存したりといったことはしない。

しかし、普通に考えて、sedコマンドを使用する場合、
「編集した内容をファイルに保存したい」という場合がほとんどだろう。

そんなときは、「-i」オプションを付与すると実行内容を保存することが可能だ。

sed -i '置換条件' ファイルPATH

以下は、-iオプションでsedコマンドの実行結果を保存する例

MacBook-Air-2:test_Dir root# cat test.txt

AAAAxxxAAAA
BBBBxxxBBBB
CCCCxxxCCCC
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

MacBook-Air-2:test_Dir root# sed -i 's/xxx/ZZZ/g' test.txt

AAAAZZZAAAA # 置換
BBBBZZZBBBB # 置換
CCCCZZZCCCC # 置換
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

#上記内容で保存まで完了

保存時に直前の状態のバックアップを取得させる

保存時に直前の状態のバックアップを取得させることも出来る。

sed -i.バックアップファイルの末尾に付与する文字列 '置換条件' ファイルPATHCopy

以下は、保存時に直前の状態のバックアップを取得した上で、実行結果を保存する例

MacBook-Air-2:test_Dir root# sed -i.$(date +%Y%m%d) 's/xxx/ZZZ/g' test.txt

AAAAZZZAAAA # 置換
BBBBZZZBBBB # 置換
CCCCZZZCCCC # 置換
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

#バックアップを取得して保存まで完了


MacBook-Air-2:test_Dir root# cat test.txt.20211016

AAAAZZZAAAA
BBBBZZZBBBB
CCCCZZZCCCC
DDDDyyyDDDD
EEEEyyyEEEE
FFFFyyyFFFF

末尾につける拡張子しかバックアップファイルの名前を変更できない仕様なので、注意。

複数の置換条件を適用する

複数の置換条件を使用する場合は、
「-e」オプションでそれぞれの置換条件を指定してあげると良い。

sed -e '置換条件' -e '置換条件' ...

以下は、xxx→ZZZに置換する条件と、yyy→WWWに置換する条件を指定する例だ。

MacBook-Air-2:test_Dir root# sed -e 's/xxx/ZZZ/g' -e 's/yyy/WWW/g' test.txt

AAAAZZZAAAA # xxx→ZZZに置換
BBBBZZZBBBB # xxx→ZZZに置換
CCCCZZZCCCC # xxx→ZZZに置換
DDDDWWWDDDD # yyy→WWWに置換
EEEEWWWEEEE # yyy→WWWに置換
FFFFWWWFFFF # yyy→WWWに置換

「;」で区切って複数の置換条件を指定することも可能

なお、以下のように
「;」で区切ることで複数の置換条件を指定することも可能だ。

sed '置換条件;置換条件' ...

以下は、xxx→ZZZに置換する条件と、5行目をaaaaaaaに置換する条件を指定する例だ。

sed -e 's/xxx/ZZZ/g;5c aaaaaaa' test.txt

AAAAZZZAAAA # xxx→ZZZに置換
BBBBZZZBBBB # xxx→ZZZに置換
CCCCZZZCCCC # xxx→ZZZに置換
DDDDyyyDDDD
aaaaaaa     # aaaaaaaに置換
FFFFyyyFFFF

外部ファイルに書いた置換条件を読み込む

sedコマンドでは、
「-f」オプションを使用することで、外部ファイルに記述した置換条件を読み込んで実行することが出来る。

sed -f スクリプトファイルPATH

以下は、外部ファイル「sed_script」を読み込んで置換する例

MacBook-Air-2:test_Dir root# cat sed_script 

s/xxx/ZZZ/g
5c aaaaaaa


MacBook-Air-2:test_Dir root# sed -f sed_script test.txt

AAAAZZZAAAA # xxx→ZZZに置換
BBBBZZZBBBB # xxx→ZZZに置換
CCCCZZZCCCC # xxx→ZZZに置換
DDDDyyyDDDD
aaaaaaa     # aaaaaaaに置換
FFFFyyyFFFF

条件部分を外部ファイルに記述することで、より柔軟に、そして保守性を保って運用可能となる。

指定した条件の行を出力する

sedコマンドでは、
pコマンドで、指定した条件の行のみ出力させることが可能だ。

なお、この際「-n」を付与しないと動作しないので注意。

sed -n '行の条件p' 対象ファイル

2行目のみ出力する

MacBook-Air-2:test_Dir root# sed -n '2p' test.txt

BBBBxxxBBBB

2行目~5行目までを出力する

MacBook-Air-2:test_Dir root# sed -n '2,5p' test.txt

BBBBxxxBBBB
CCCCxxxCCCC
DDDDyyyDDDD
EEEEyyyEEEE

「xxx」を含む行のみ出力する

MacBook-Air-2:test_Dir root# sed -n '/xxx/p' test.txt

AAAAxxxAAAA
BBBBxxxBBBB
CCCCxxxCCCC

sedコマンドの基本的な使い方一覧(まとめ)

最後にsedコマンドの基本的な使い方の一覧を紹介する。

sedコマンドで指定出来る処理内容は非常に多い。なので全部覚えようとしても大抵の人は無理なので、ここでは「こんなことができるのね」くらいに捉えてもらえればOKだ。

コメント

  • # … #以降はコメントとして取り扱う

置換

  • c … 行をまるごと置換する
  • s … 文字列を置換する
  • y … 一文字ずつ置換する

追加・挿入

  • a … 行を”追加”する
  • i … 行を”挿入”する

なお、複数行追加・挿入する場合は「\n」で改行を表現する。

削除

  • d … 行を削除する
  • D … 先頭セグメントから最初の改行までを削除する

入力

  • r ファイル名 … ファイルの内容を読み込む
  • n … パターンスペースを入力の次の行で置換
  • N … 入力の次の行をパターンスペースに追加し,改行文字を埋め込む(‘\n’ で改行として認識されるのはここで埋め込まれた改行文字だけとなる)

出力

  • p … パターンスペースを標準出力に出力
  • P … パターンスペースの先頭セグメントから最初の改行までを標準出力に出力
  • | … 明白な形式でパターンスペースを標準出力に一覧表示する
  • = … 現在の行番号を 1 行として標準出力に出力(タブ文字などは対応するエスケープシーケンスとして表示され,非印字文字は 8 進数表記法で表示される)
  • w ファイル名 … ファイルにパターンスペースを追加する。w コマンドが最初に呼び出されたときにはファイルの中身はクリアされる

ホールドスペースの利用

  • g … パターンスペースの内容をホールドスペースの内容で置換
  • G … ホールドスペースの内容をパターンスペースに追加
  • h … ホールドスペースの内容をパターンスペースの内容で置換
  • H … パターンスペースの内容をホールドスペースに追加
  • x … パターンスペースの内容とホールドスペースの内容を交換する

グループ化

  • {コマンドリスト}

制御構造

  • b ラベル … 指定したラベルの : コマンドに分岐
  • t ラベル … 入力行の最新の読みとりまたは t の実行以降に代入が行われている場合,指定したラベルの : コマンドに分岐
  • : ラベル … ラベル付け
  • q … 終了

タイトルとURLをコピーしました