【Linux】sedコマンドを使ってみる(ChatGPT)

ストリームエディター(sed)は、テキストファイルを簡単に操作できる Linux のコマンドラインツールです。大きなテキストの編集や変換に向いていて、行単位で処理します。正規表現にも対応しています。この記事では、sed の主な機能とコマンドの使い方を、実行例で確認します。

この記事でわかること
  1. sed の基本的な動き方と、置換(s)・削除(d)・出力(p)・挿入(i)の使い方
  2. ChatGPT にプロンプトを入力して sed のコマンドを作り、実行して確認する学び方
  3. -i でファイルが書き換わることと、-i.bak でバックアップを残す方法
検証環境

ホスト名は hirotano、ユーザー名は hirotano です。実行例は、サンプルファイル sample.txt に対して実行した結果です。

前提(ChatGPT)

この記事では、AI ツールの ChatGPT(GPT-3.5)を使います。実現したい処理をプロンプトとして入力すると、自然言語から、適切なコマンドを出力させられます。そのコマンドを実行して確認すれば、多くの実行例を学べます。今後は、コマンドの構文を覚えるよりも、プロンプトを使って学ぶスタイルに変わっていくと思われます。

注意:ChatGPT の出力は毎回変わる

ChatGPT の出力は、プロンプトを実行するたびに異なります。記事のとおりに出力されるとは限りません。必ず出力結果を確認してから、コマンドを実行してください。

sed の基本

sed は、入力を1行ずつ読み込み、指定したコマンドを適用して、結果を出力します。何も指定しない場合、結果は画面(標準出力)に表示されて、元のファイルは変わりません。-i オプションを付けたときだけ、元のファイルが書き換わります。

入力sample.txt1行ずつsedコマンドを適用する(置換・削除・挿入など)既定画面に表示-iファイルを上書き-n を付けると、行の自動出力を止める。そのとき p コマンドを実行した行だけが出力される
図1 sed の処理の流れ

この記事で使うオプションとコマンドは、次のとおりです。

オプション・コマンド意味
-iファイルを直接書き換える。-i.bak のように、直後に拡張子を付けると、元のファイルをバックアップとして残す
-n行の自動出力を止める。p コマンドで指定した行だけを出力するときに使う
-eスクリプト(処理)を指定する。複数回指定すると、指定した順に適用される
s/検索/置換/g文字列を置換する。g を付けると、1行の中のすべての一致を置換する
d行を削除する
p行を出力する
i指定した行の前にテキストを挿入する

コマンドの前に、行番号(2d)や、スラッシュで囲んだ正規表現(/sedコマンド/d)を書くと、処理する行を絞り込めます。

補足:-i を付ける前に確認する

-i を付けて実行すると、元のファイルが上書きされます。ChatGPT が出力するコマンドには、-i が付いていることが多いので、実行前に、-i を外して実行し、画面に表示される結果を確認すると安全です。バックアップが必要なときは、-i.bak を使います。

サンプルファイルの準備

まず、sed を学ぶためのサンプルファイルを作るように、ChatGPT に指示します。

プロンプト(ChatGPT に入力)

Ubuntuでsedコマンドを学習したいです。学習に使用するサンプルテキスト(3行、全体合計50~80字)を作成してください。

ChatGPT は、次の3行のサンプルテキストを出力しました。

UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。

echo コマンドなどで、カレントディレクトリに sample.txt というファイルを作成します。たとえば、次のようにヒアドキュメントで作成できます。

$ cat > sample.txt <<'EOF'
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
EOF

以降の実行例は、この sample.txt を使います。各例では、実行前の sample.txt は、この3行の状態に戻してから実行しています。

テキスト置換

ファイル内の文字をすべて置換する

プロンプト(ChatGPT に入力)

sample.txtファイル内の文字のすべての「Ubuntu」を「Linux」に置換するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -i 's/Ubuntu/Linux/g' sample.txt
部分意味
-iファイルを直接書き換える
s/Ubuntu/Linux/gUbuntu を Linux に置換する。最後の g で、1行の中のすべての一致を置換する
sample.txt対象のファイル

実行例

hirotano@hirotano:~$ cat sample.txt 
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -i 's/Ubuntu/Linux/g' sample.txt
hirotano@hirotano:~$ cat sample.txt                      
LinuxはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$

複数の置換条件を一括で実行する

プロンプト(ChatGPT に入力)

sample.txt内のすべての「Linux」を「Unix」に、すべての「Ubuntu」を「Fedora」に置換するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -i -e 's/Linux/Unix/g' -e 's/Ubuntu/Fedora/g' sample.txt
部分意味
-e 's/Linux/Unix/g'1つ目の置換。Linux を Unix に置換する
-e 's/Ubuntu/Fedora/g'2つ目の置換。Ubuntu を Fedora に置換する

実行例

hirotano@hirotano:~$ cat sample.txt 
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -i -e 's/Linux/Unix/g' -e 's/Ubuntu/Fedora/g' sample.txt
hirotano@hirotano:~$ cat sample.txt 
FedoraはUnixディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$
補足:-e は指定した順に適用される

-e で指定した処理は、書いた順に、1行ずつ適用されます。この例では、Linux を Unix にしたあとで Ubuntu を Fedora にするので、互いに影響しません。順番を逆にして、Ubuntu を Linux にしたあとで Linux を Unix にすると、置換した結果も、次の置換の対象になります。

アルファベット小文字をすべて大文字に変更(正規表現)

プロンプト(ChatGPT に入力)

ファイルsample.txt内の小文字アルファベットをすべて大文字に置換するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -i 's/[a-z]/\U&/g' sample.txt
部分意味
[a-z]半角の英小文字1文字にマッチする正規表現
\U置換後の文字を大文字にする(GNU sed の拡張)
&マッチした文字列そのもの。ここでは、見つかった英小文字1文字
g1行の中のすべての一致を置換する

実行例

hirotano@hirotano:~$ cat sample.txt 
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -i 's/[a-z]/\U&/g' sample.txt
hirotano@hirotano:~$ cat sample.txt                   
UBUNTUはLINUXディストリビューションのひとつです。
SEDコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$

日本語の文字は変わりません。sedコマンド の sed の部分が SED になります。

テキスト削除

指定した行番号を削除

プロンプト(ChatGPT に入力)

sample.txtの2行目を削除するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -i '2d' sample.txt
部分意味
2d2行目(2)を削除(d)する

実行例

hirotano@hirotano:~$ cat sample.txt 
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -i '2d' sample.txt
hirotano@hirotano:~$ cat sample.txt        
UbuntuはLinuxディストリビューションのひとつです。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$

指定した文字を含む行を削除

プロンプト(ChatGPT に入力)

ファイルsample.txt内の「sedコマンド」が含まれる行をすべて削除するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -i '/sedコマンド/d' sample.txt
部分意味
/sedコマンド/sedコマンド を含む行を選ぶ正規表現(アドレス)
d選んだ行を削除する

実行例

hirotano@hirotano:~$ cat sample.txt 
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -i '/sedコマンド/d' sample.txt
hirotano@hirotano:~$ cat sample.txt                    
UbuntuはLinuxディストリビューションのひとつです。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$

テキスト抽出

指定した文字列を含む行を抽出

プロンプト(ChatGPT に入力)

ファイルsample.txt内の「Ubuntu」という文字列が含まれる行をすべて抽出するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -n '/Ubuntu/p' sample.txt
部分意味
-n行の自動出力を止める
/Ubuntu/pUbuntu を含む行だけを出力(p)する

実行例

hirotano@hirotano:~$ cat sample.txt 
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -n '/Ubuntu/p' sample.txt
UbuntuはLinuxディストリビューションのひとつです。
hirotano@hirotano:~$

行を抽出するだけなら、grep Ubuntu sample.txt でも同じ結果になります。

指定した文字列の間にある文字列を抽出

プロンプト(ChatGPT に入力)

ファイルsample.txtから「Ubuntuは」と「です。」の間にある文字列を抽出するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -n 's/.*Ubuntuは\(.*\)です.*/\1/p' sample.txt
部分意味
-n行の自動出力を止める
.*Ubuntuは\(.*\)です.*行全体にマッチする正規表現。.* は任意の文字列。\( \) で囲んだ部分(Ubuntuは と です の間)を、あとで参照するために覚える
\1\( \) で覚えた部分。行全体を、この部分だけに置き換える
p置換が行われた行を出力する

実行例

hirotano@hirotano:~$ cat sample.txt 
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -n 's/.*Ubuntuは\(.*\)です.*/\1/p' sample.txt
Linuxディストリビューションのひとつ
hirotano@hirotano:~$
補足:.* は最長一致

.* は、できるだけ長く一致します。同じ行に です が複数ある場合は、最後の です の手前までが抽出されます。たとえば、UbuntuはAですBです。 という行では、AですB が抽出されます。

テキスト挿入

指定した行にテキストを挿入

プロンプト(ChatGPT に入力)

ファイルsample.txt内の「sedコマンド」が含まれる行の先頭にすべて「#」を挿入するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -i '/sedコマンド/s/^/#/' sample.txt
部分意味
/sedコマンド/sedコマンド を含む行だけを対象にする
s/^/#/行頭(^)を # に置換する。結果として、行頭に # が挿入される

実行例

hirotano@hirotano:~$ cat sample.txt                   
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -i '/sedコマンド/s/^/#/' sample.txt
hirotano@hirotano:~$ cat sample.txt                         
UbuntuはLinuxディストリビューションのひとつです。
#sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$

指定した行に新しい行を挿入

プロンプト(ChatGPT に入力)

ファイルsample.txtの3行目の上に新しい行として、「この行は新しい行です」を挿入するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -i '3iこの行は新しい行です' sample.txt
部分意味
3i3行目の前に、新しい行を挿入(i)する
この行は新しい行です挿入するテキスト。i の直後に続けて書く

実行例

hirotano@hirotano:~$ cat sample.txt               
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -i '3iこの行は新しい行です' sample.txt
hirotano@hirotano:~$ cat sample.txt                            
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
この行は新しい行です
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$
補足:i の書き方は GNU sed の拡張

3iテキスト のように、i の直後にテキストを続けて書ける形は、GNU sed の拡張です。GNU sed 以外の sed では、i の後ろに \ と改行を入れる書き方が必要な場合があります。

その他

指定した文字の置換と指定した行の削除を一括で編集

プロンプト(ChatGPT に入力)

ファイルsample.txt内の「Ubuntu」という文字列をすべて「Linux」に置換し、「sedコマンド」が含まれる行をすべて削除するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -i -e 's/Ubuntu/Linux/g' -e '/sedコマンド/d' sample.txt
部分意味
-e 's/Ubuntu/Linux/g'1つ目の処理。Ubuntu を Linux に置換する
-e '/sedコマンド/d'2つ目の処理。sedコマンド を含む行を削除する

実行例

hirotano@hirotano:~$ cat sample.txt
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -i -e 's/Ubuntu/Linux/g' -e '/sedコマンド/d' sample.txt
hirotano@hirotano:~$ cat sample.txt
LinuxはLinuxディストリビューションのひとつです。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$

バックアップファイルの作成

プロンプト(ChatGPT に入力)

元のファイルsample.txtをsample.txt.bakという名前のバックアップファイルとして保存し、同時に「Ubuntu」という文字列をすべて「Linux」に置換するsedコマンドを出力してください。

ChatGPT が出力したコマンド

$ sed -i.bak 's/Ubuntu/Linux/g' sample.txt
部分意味
-i.bak-i の直後に、バックアップの拡張子 .bak を付ける。スペースは入れない。書き換える前の内容が sample.txt.bak として残る

実行例

hirotano@hirotano:~$ cat sample.txt 
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ sed -i.bak 's/Ubuntu/Linux/g' sample.txt
hirotano@hirotano:~$ ls
bin  sample.txt  sample.txt.bak
hirotano@hirotano:~$ cat sample.txt                          
LinuxはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$ cat sample.txt.bak 
UbuntuはLinuxディストリビューションのひとつです。
sedコマンドはテキストの編集に用いられます。
正規表現を使ってテキストを置換することができます。
hirotano@hirotano:~$

ls の結果の bin は、この環境にもともとあったディレクトリです。sample.txt.bak には、置換前の内容が残っています。

まとめ

sed で何ができるのかを覚えておけば、コマンドの書き方を無理に覚える必要はありません。ChatGPT で簡単にコマンドを作成できます。ただし、ChatGPT の出力は毎回変わり、-i でファイルが書き換わるので、実行前に、-i を外して結果を確認します。

やりたいことコマンドの例
文字列を置換するsed -i 's/Ubuntu/Linux/g' sample.txt
複数の置換を一括で行うsed -i -e 's/A/B/g' -e 's/C/D/g' sample.txt
英小文字を大文字にするsed -i 's/[a-z]/\U&/g' sample.txt
指定した行を削除するsed -i '2d' sample.txt
文字列を含む行を削除するsed -i '/sedコマンド/d' sample.txt
文字列を含む行を抽出するsed -n '/Ubuntu/p' sample.txt
2つの文字列の間を抽出するsed -n 's/.*Ubuntuは\(.*\)です.*/\1/p' sample.txt
行頭に文字を挿入するsed -i '/sedコマンド/s/^/#/' sample.txt
指定した行の前に行を挿入するsed -i '3iこの行は新しい行です' sample.txt
バックアップを残して置換するsed -i.bak 's/Ubuntu/Linux/g' sample.txt

コメント