テキストを整形する

INPUT · スライド

文字列を置きかえる(`sed`)

01 / 07

`tr` にできなかったこと

tr は文字を1文字ずつ置きかえる道具だったね。だからこれができなかったんだ。

```
error という言葉を ERROR に変えたい
```

trerrorERROR を渡しても、eErRrRoOrR という文字ごとの対応になってしまう。言葉として扱ってくれないんだ。

言葉(文字列)を置きかえる道具が sed だよ。stream editor(流れを編集するもの)の略だね。

02 / 07

`s/前/後/` が基本の形

sed でいちばん使うのは s(substitute = 置きかえ)だよ。

```
sed 's/error/ERROR/' log.txt
```

読み方はこうだね。

```
s / 探すもの / 置きかえるもの /
```

/ は区切りの記号で、3つ必要だよ。シングルクォートで囲むのは、/* をシェルに勘違いされないためだね。

tr と違ってファイル名を書けるよ。< もパイプも使えるけれど、直接書けるのが楽だね。

~ $ sed 's/error/ERROR/' log.txtERROR: disk fullok: startedERROR: no route

03 / 07

`g` を付けないと1回だけ

ここが引っかかりやすいところだよ。sed は既定で各行の最初の1つだけを置きかえるんだ。

```
~ $ sed 's/one/1/' kasanari.txt
1 one one
two two
```

one が3つあるのに、1つ目だけ変わったね。

全部変えたいときは最後に g(global)を付けるよ。

```
~ $ sed 's/one/1/g' kasanari.txt
1 1 1
two two
```

g を忘れて「1つしか変わらない」のは誰でも一度はやる間違いだよ。逆に「1つ目だけ変えたい」場面もあるので、既定が1回なのは無駄ではないんだ。

04 / 07

区切りは `/` でなくてもいい

パス(ファイルの場所)を置きかえたいとき、/ だらけで読めなくなるよね。

```
sed 's/\/home\/guest/\/tmp/' path.txt # 読めない
```

実は区切りは好きな文字にできるんだ。s の次に来る文字が区切りとして使われるよ。

```
sed 's|/home/guest|/tmp|' path.txt # 読める
```

|#, がよく使われるよ。

中身に出てこない文字を区切りに選ぶのがコツだね。これを知らないと、バックスラッシュだらけの読めない命令を書くことになるよ。

05 / 07

行を選ぶ、行を消す

sed は置きかえ以外もできるよ。

-np で選ぶ-n は「勝手に出さない」、p は print)

```
sed -n '2p' abcde.txt # 2行目だけ
sed -n '2,4p' abcde.txt # 2〜4行目
sed -n '$p' abcde.txt # 最後の行
```

d で消す(delete)

```
sed '2d' abcde.txt # 2行目を消す
sed '/error/d' log.txt # error を含む行を消す
```

sed '/error/d'grep -v error と同じだね。同じことが何通りかの道具でできるのはこれまでどおりだよ。

06 / 07

`-i` はファイルを書きかえる(危ない)

ここまでの sed結果を画面に出すだけで、元のファイルは変わっていないよ。

-i(in-place)を付けると、ファイルそのものを書きかえるんだ。

```
sed -i 's/error/ERROR/' log.txt
```

便利だけれど元に戻せないよ。取り消す方法は無いんだ。

安全な使い方は2つあるよ。

1. まず -i なしで打って、結果を確かめてから -i を足す
2. -i.bak と書く(log.txt.bak という控えを残してくれる)

```
sed -i.bak 's/error/ERROR/' log.txt
```

確かめてから書きかえる。これは > のときにも言ったことだね。取り返しがつかない操作の前には、必ず一度目で見るんだよ。

07 / 07

さあ、打ってみよう

ファイルは5つだよ。

  • log.txterror:ok:error: の3行
  • seiseki.csvtanaka,80suzuki,95
  • kasanari.txtone one onetwo two
  • abcde.txtae の5行
  • path.txt/home/guest/a.txt など2行

シングルクォートで囲むのを忘れないでね。囲まないとシェルが /* を勘違いすることがあるよ。

sed は奥が深い道具で、それだけで本が1冊書けるくらいだよ。でも日々の仕事で使うのは s/前/後/g がほとんどなんだ。まずはそれを手に馴染ませよう。