ストリームエディター(sed)は、テキストファイルを簡単に操作できる Linux のコマンドラインツールです。大きなテキストの編集や変換に向いていて、行単位で処理します。正規表現にも対応しています。この記事では、sed の主な機能とコマンドの使い方を、実行例で確認します。
- sed の基本的な動き方と、置換(
s)・削除(d)・出力(p)・挿入(i)の使い方 - ChatGPT にプロンプトを入力して sed のコマンドを作り、実行して確認する学び方
-iでファイルが書き換わることと、-i.bakでバックアップを残す方法
ホスト名は hirotano、ユーザー名は hirotano です。実行例は、サンプルファイル sample.txt に対して実行した結果です。
前提(ChatGPT)
この記事では、AI ツールの ChatGPT(GPT-3.5)を使います。実現したい処理をプロンプトとして入力すると、自然言語から、適切なコマンドを出力させられます。そのコマンドを実行して確認すれば、多くの実行例を学べます。今後は、コマンドの構文を覚えるよりも、プロンプトを使って学ぶスタイルに変わっていくと思われます。
ChatGPT の出力は、プロンプトを実行するたびに異なります。記事のとおりに出力されるとは限りません。必ず出力結果を確認してから、コマンドを実行してください。
sed の基本
sed は、入力を1行ずつ読み込み、指定したコマンドを適用して、結果を出力します。何も指定しない場合、結果は画面(標準出力)に表示されて、元のファイルは変わりません。-i オプションを付けたときだけ、元のファイルが書き換わります。
この記事で使うオプションとコマンドは、次のとおりです。
| オプション・コマンド | 意味 |
|---|---|
-i | ファイルを直接書き換える。-i.bak のように、直後に拡張子を付けると、元のファイルをバックアップとして残す |
-n | 行の自動出力を止める。p コマンドで指定した行だけを出力するときに使う |
-e | スクリプト(処理)を指定する。複数回指定すると、指定した順に適用される |
s/検索/置換/g | 文字列を置換する。g を付けると、1行の中のすべての一致を置換する |
d | 行を削除する |
p | 行を出力する |
i | 指定した行の前にテキストを挿入する |
コマンドの前に、行番号(2d)や、スラッシュで囲んだ正規表現(/sedコマンド/d)を書くと、処理する行を絞り込めます。
-i を付けて実行すると、元のファイルが上書きされます。ChatGPT が出力するコマンドには、-i が付いていることが多いので、実行前に、-i を外して実行し、画面に表示される結果を確認すると安全です。バックアップが必要なときは、-i.bak を使います。
サンプルファイルの準備
まず、sed を学ぶためのサンプルファイルを作るように、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行の状態に戻してから実行しています。
テキスト置換
ファイル内の文字をすべて置換する
sample.txtファイル内の文字のすべての「Ubuntu」を「Linux」に置換するsedコマンドを出力してください。
ChatGPT が出力したコマンド
$ sed -i 's/Ubuntu/Linux/g' sample.txt
| 部分 | 意味 |
|---|---|
-i | ファイルを直接書き換える |
s/Ubuntu/Linux/g | Ubuntu を 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:~$
複数の置換条件を一括で実行する
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 で指定した処理は、書いた順に、1行ずつ適用されます。この例では、Linux を Unix にしたあとで Ubuntu を Fedora にするので、互いに影響しません。順番を逆にして、Ubuntu を Linux にしたあとで Linux を Unix にすると、置換した結果も、次の置換の対象になります。
アルファベット小文字をすべて大文字に変更(正規表現)
ファイルsample.txt内の小文字アルファベットをすべて大文字に置換するsedコマンドを出力してください。
ChatGPT が出力したコマンド
$ sed -i 's/[a-z]/\U&/g' sample.txt
| 部分 | 意味 |
|---|---|
[a-z] | 半角の英小文字1文字にマッチする正規表現 |
\U | 置換後の文字を大文字にする(GNU sed の拡張) |
& | マッチした文字列そのもの。ここでは、見つかった英小文字1文字 |
g | 1行の中のすべての一致を置換する |
実行例
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 になります。
テキスト削除
指定した行番号を削除
sample.txtの2行目を削除するsedコマンドを出力してください。
ChatGPT が出力したコマンド
$ sed -i '2d' sample.txt
| 部分 | 意味 |
|---|---|
2d | 2行目(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:~$
指定した文字を含む行を削除
ファイル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:~$
テキスト抽出
指定した文字列を含む行を抽出
ファイルsample.txt内の「Ubuntu」という文字列が含まれる行をすべて抽出するsedコマンドを出力してください。
ChatGPT が出力したコマンド
$ sed -n '/Ubuntu/p' sample.txt
| 部分 | 意味 |
|---|---|
-n | 行の自動出力を止める |
/Ubuntu/p | Ubuntu を含む行だけを出力(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 でも同じ結果になります。
指定した文字列の間にある文字列を抽出
ファイル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 が抽出されます。
テキスト挿入
指定した行にテキストを挿入
ファイル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:~$
指定した行に新しい行を挿入
ファイルsample.txtの3行目の上に新しい行として、「この行は新しい行です」を挿入するsedコマンドを出力してください。
ChatGPT が出力したコマンド
$ sed -i '3iこの行は新しい行です' sample.txt
| 部分 | 意味 |
|---|---|
3i | 3行目の前に、新しい行を挿入(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:~$
3iテキスト のように、i の直後にテキストを続けて書ける形は、GNU sed の拡張です。GNU sed 以外の sed では、i の後ろに \ と改行を入れる書き方が必要な場合があります。
その他
指定した文字の置換と指定した行の削除を一括で編集
ファイル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:~$
バックアップファイルの作成
元のファイル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 |
コメント