テキストを整形する

INPUT · スライド

違いを出す(`diff`)

01 / 07

「どこが違うの?」に答える道具

この章の最後は diff だよ。2つのファイルの違いを出す道具だね。

こういう場面で使うよ。

  • 設定ファイルを直した。どこを変えたんだっけ?
  • 動いていたときの控えと今のもの、何が違う?
  • 2つの名簿、どちらにしかいない人は誰?

目で見比べるのは大変だし、見落とすよね。diff なら違うところだけを教えてくれるんだ。

02 / 07

`-` と `+` で読む

a.txtb.txt を比べてみるよ。

```
~ $ diff a.txt b.txt
--- a.txt
+++ b.txt
@@ -1,3 +1,3 @@
ringo
-mikan
+budou
banana
```

読み方はこうだよ。

| 行の頭 | 意味 |
| --- | --- |
| (空白) | 両方にある(変わっていない) |
| - | 1つ目にだけある(消えた) |
| + | 2つ目にだけある(増えた) |

つまり「mikanbudou に変わった」と言っているんだ。

--- a.txt+++ b.txt は、どちらが - でどちらが + かの説明だよ。- は左、+ は右だね。

03 / 07

`@@` は場所を表す

@@ -1,3 +1,3 @@ という行が気になるよね。これはどのあたりの話かを表しているよ。

```
@@ -1,3 +1,3 @@
↑ ↑
1つ目の 2つ目の
1行目から3行分
```

大きなファイルでは、違うところだけを抜き出して見せてくれるんだ。そのとき「これは何行目付近の話です」と教えてくれるのが @@ の行だよ。

この形は unified 形式(統一形式)と呼ばれていて、git diff やソフトウェアの修正パッチもまったく同じ形だよ。

ここで読めるようになっておくと、ずっと役に立つからね。プログラムの変更を人に見てもらうとき、必ずこの形で見せるんだ。

04 / 07

同じときは何も言わない

a.txtc.txt は中身が同じだよ。

```
~ $ diff a.txt c.txt
~ $
```

何も出ないね。grepfind と同じで、「言うことが無い = 問題なし」だよ。

はっきり言ってほしいときは -s を付けるよ。

```
~ $ diff -s a.txt c.txt
Files a.txt and c.txt are identical
```

逆に、中身は見せずに「違うかどうか」だけ知りたいときは -q だね。

```
~ $ diff -q a.txt b.txt
Files a.txt and b.txt differ
```

大きなファイルで、違いの中身より「同じか違うか」だけが知りたいときに便利だよ。

05 / 07

終了ステータスで判断できる

diff は結果を終了ステータスでも教えてくれるよ。

| ステータス | 意味 |
| --- | --- |
| 0 | 同じ |
| 1 | 違う |

直前の終了ステータスは $? で見られるよ。

```
diff a.txt b.txt; echo "code=$?"
```

これが便利なのは、プログラムから使えることだよ。人が目で見るのではなく、機械が判断できるんだ。

```
if diff -q a.txt b.txt > /dev/null; then
echo 同じ
else
echo 違う
fi
```

この if の書き方は章11でやるよ。いまは「diff は答えを数でも返す」と知っておいて。自動で見張る仕組みは、これで作れるんだ。

06 / 07

見えない違いも見つける

diff目に見えない違いも見つけてくれるよ。

d.txta.txt とほとんど同じだけれど、1行目の末尾に空白が2つ入っているんだ。

```
~ $ diff a.txt d.txt
@@ -1,3 +1,3 @@
-ringo
+ringo
mikan
banana
```

-ringo+ringo同じに見えるのに違いとして出たね。末尾の空白は目に見えないからだよ。

これは「見た目は同じなのに動かない」という不具合の原因になるよ。だから diff が教えてくれるのは親切なんだ。

空白の違いを無視したいときは -b を付けるよ。

```
diff -b a.txt d.txt # 何も出ない
```

07 / 07

さあ、打ってみよう

ファイルは5つだよ。

  • a.txtringomikanbanana
  • b.txtringobudoubanana(真ん中が違う)
  • c.txta.txt同じ
  • d.txta.txt と同じに見えるが1行目の末尾に空白
  • e.txta.txtkaki を足したもの

どれを比べるかで結果が変わるので、順番に試してみよう。

diff A B の順番は大事だよ。入れかえると -+ が逆になるからね。「前 → 後」の順に書く、と決めておくと混乱しないよ。