Envaderを利用して、sort/uniq/diffコマンドを体験して学ぶ

30代後半、未経験からIT業界のエンジニア転職へ挑戦している、kobakichiです。

今回も環境構築が不要、オンラインでLinux環境の学習ができる[Envader](https://envader.plus/)を利用して、コマンドの動きを体験しながら学んでみたのでその振り返りとまとめです。

Envaderについて気になる方用に、下記にリンクを貼っておきますので参考にどうぞ。

[Envaderコース一覧](https://envader.plus/course)

[今回使用したシナリオ](https://envader.plus/course/1/scenario/1018)

## sortコマンド

sortコマンドは、`行単位でファイルの中身を並べ替える`事ができて、`デフォルトでは昇順で並べ替え`が行われます。

ただ、出力されて画面に表示される時に並べ替えが行われるだけで、`その内容でファイルが上書きされる訳ではない`とのことなので、忘れないようにしないといけないな。と思いました。

出力されたら上書きされた感じがするけど、再度ファイルを表示してみると元の並べ替えがされていない状態に戻ってしまうんですね。

### 使い方の基本

```bash
sort ファイル名
```

基本はこれ。

試しにEnvaderで実行してみる。

```bash
envader@172-19-1-2:~$ head score.txt
星野戸敷 英語 34
水上綾奈 英語 71
平山絢菜 数学 99
新田胡桃 英語 5
波多野正子 国語 9
滝川咲菜 国語 97
栗原雄二郎 英語 46
滝川咲菜 数学 98
滝川咲菜 数学 98
滝川咲菜 数学 98

envader@172-19-1-2:~$ sort score.txt | head
安西幸揮 英語 25
安西幸揮 国語 47
安西幸揮 数学 97
伊東文香 英語 66
伊東文香 国語 89
伊東文香 数学 71
井川充 英語 62
井川充 国語 44
井川充 数学 74
磯野茜 英語 85
```
おお。
名前を基準にアイウエオ順に並べ替えられている。

さらに的を絞って検索したい時にはオプションが使えるようです。

### sortコマンド　オプション

|オプション|内容|
|---|---|
|-b|行頭の空白は無視する|
|-f|大文字小文字の区別はしない|
|-r|降順に並べ替える|
|-n|数字の大小を基準に並べ替える|
|-k|フィールド(空白)を指定して並べ替える|
|-u|同一行は一つ目だけを出力する|

オプションを使ってsortコマンドを実行してみます。

```bash
# -rで降順に並べ替える

envader@172-19-1-2:~$ sort -r score.txt | head
和田義和 数学 60
和田義和 国語 1
和田義和 英語 63
柳川安弘 数学 76
柳川安弘 国語 93
柳川安弘 英語 17
矢吹千恵 数学 81
矢吹千恵 国語 6
矢吹千恵 英語 21
野田菜穂 数学 12
```

```bash
# -k で3列目の点数を基準に並べ替え

envader@172-19-1-2:~$ sort -k 3 score.txt | head
笹原鈴 英語 0
西岡由子 英語 0
谷内嘉男 英語 0
八木茉奈 国語 0
富永政男 英語 0
富永政男 国語 0
稲村沙也香 英語 1
熊倉有沙 英語 1
堀百合 数学 1
和田義和 国語 1

# 得点の高い順で並べ替え

envader@172-19-1-2:~$ sort -r -k 3 score.txt | head
平山絢菜 数学 99
前川琉菜 数学 99
西岡由子 国語 99
西岡由子 国語 99
西岡由子 国語 99
西岡由子 国語 99
上条敬一 数学 99
吉野清茂 英語 99
関口三朗 国語 99
園田明音 国語 99
```

と思ったのですが、ここで落とし穴。
通常で`sort`コマンドでは、数字を数値として捉えずに、文字として扱ってしまうらしく、これだと正しく数字を元に並べ替えられていませんでした。

そんな時に使うのが`-n`オプションなんですね。

```bash
# 実は100点が居ました。

envader@172-19-1-2:~$ sort -k 3 -n score.txt | tail
西岡由子 国語 99
西岡由子 国語 99
西岡由子 国語 99
前川琉菜 数学 99
平山絢菜 数学 99
羽田綾奈 国語 100
高谷宣彦 国語 100
大高義男 国語 100
棚橋嘉子 数学 100
堀田夏未翔 数学 100
```


## uniqコマンド
テキストファイルの中で、重複した行を一つにするために使用するコマンド。

隣り合った行で重複しているものしか一つにまとめられないので、`sort`コマンドと一緒に使うことを推奨されています。

### 使い方の基本
```bash
uniq ファイル名
```

### uniqコマンドオプション

|オプション|意味|
|---|---|
|-i|大文字小文字を区別しないで重複行を一つにする|
|-c|重複している行をカウントして数字を表示する|
|-u|重複していない行のみ出力する|
|-d|重複している行のみ出力する|

実際に使ってみるとこんな感じです。

```bash

# 滝川さんが重複
envader@172-19-1-2:~$ cat score.txt | head
星野戸敷 英語 34
水上綾奈 英語 71
平山絢菜 数学 99
新田胡桃 英語 5
波多野正子 国語 9
滝川咲菜 国語 97
栗原雄二郎 英語 46
滝川咲菜 数学 98
滝川咲菜 数学 98
滝川咲菜 数学 98

# 滝川さんの重複が取れている
envader@172-19-1-2:~$ uniq score.txt | head
星野戸敷 英語 34
水上綾奈 英語 71
平山絢菜 数学 99
新田胡桃 英語 5
波多野正子 国語 9
滝川咲菜 国語 97
栗原雄二郎 英語 46
滝川咲菜 数学 98
熊倉有沙 国語 23
川越美津子 国語 21
```

#### 注意点
ここで私がハマったのは、`uniq`コマンドは**重複する行**を調べて、重複する行があれば1行にまとめて出力するコマンド。
今回の場合、使用しているデータは1行に3つあるので、たとえ隣同士の名前が重複していても他のデータが重複していなければまとめる対象にはならないということです。

~~これに気づくまで半日かかりました。~~
気をつけましょう。


`sort`を使って`uniq`してみる

```bash
# これだと一番下の羽田さんが科目、得点共に重複している。

envader@172-19-1-2:~$ sort score.txt | head -25
安西幸揮 英語 25
安西幸揮 国語 47
安西幸揮 数学 97
伊東文香 英語 66
伊東文香 国語 89
伊東文香 数学 71
井川充 英語 62
井川充 国語 44
井川充 数学 74
磯野茜 英語 85
磯野茜 国語 59
井川充 国語 44
井川充 数学 74
磯野茜 英語 85
磯野茜 国語 59
磯野茜 数学 39
磯野里佳 英語 94
磯野里佳 国語 73
磯野里佳 数学 55
稲村沙也香 英語 1
稲村沙也香 国語 69
稲村沙也香 数学 32
稲葉令子 英語 23
稲葉令子 国語 33
稲葉令子 数学 8
羽田綾奈 英語 35
羽田綾奈 英語 35
羽田綾奈 英語 35
羽田綾奈 英語 35
```

```bash
# 羽田さんの重複がまとめられている

envader@172-19-1-2:~$ sort score.txt | head -25 | uniq
安西幸揮 英語 25
安西幸揮 国語 47
安西幸揮 数学 97
伊東文香 英語 66
伊東文香 国語 89
伊東文香 数学 71
井川充 英語 62
井川充 国語 44
井川充 数学 74
磯野茜 英語 85
磯野茜 国語 59
磯野茜 数学 39
磯野里佳 英語 94
磯野里佳 国語 73
磯野里佳 数学 55
稲村沙也香 英語 1
稲村沙也香 国語 69
稲村沙也香 数学 32
稲葉令子 英語 23
稲葉令子 国語 33
稲葉令子 数学 8
羽田綾奈 英語 35
```

```bash
# -dオプションで重複した行だけを出力してみる

envader@172-19-1-2:~$ sort score.txt | head -25 | uniq -d
羽田綾奈 英語 35
```
ちゃんとできました。

#### 注意点その2
`uniq`コマンドのみでファイルを出力すると、隣り合った行で重複したものしか1つにまとめられません。
その対策として、`sort`コマンドを使ってから`uniq`コマンドを使うことで離れている重複している行も1つにまとめられるようになるので、コマンドの順番に注意が必要です。


## diffコマンド
2つのテキストファイルを比較して、異なる箇所(差分)を出力するコマンド。

### 使い方の基本
```bash
diff 1つ目のファイル名 2つ目のファイル名
```

実際に使ってみたのですが、今回は`Envader`の問題の回答をそのまま表示してしまうことになるので、内容は変更してあります。

```bash
# 単純に差分を表示する
diff secrets_ver1.txt secrets_ver2.txt
21d20
< hogehoge

# 追加した場合には<の向きが変わる。

diff secrets_ver1.txt secrets_ver2.txt
21d20
> fugafuga
```

### diffコマンド　オプション例
|オプション|説明|
|---|---|
|-s|2つのファイルが同じだった時も表示する|
|-q|ファイルが違うかどうかをチェックして、同一の場合には出力しない|
|-y|結果を横並びで表示する|
|-r|ディレクトリ同士を比較する|
|-w|空白を無視して比較する|
|-i|大文字と小文字の違いを無視する|
|-u|違いのある箇所を一つにまとめて、-と+で変更箇所を表示する|


## まとめ

今回はLinuxコマンド、`sort` `uniq` `diff`について実際に実践しながら学びました。

実務を経験している訳ではないので、実際にこのコマンド達を使う場面を想像できないのですが、きっと今後役に立つことでしょう。

**uniqコマンドはあくまで重複する行**をまとめるコマンドだということを胸に刻みつけようと思います。

最後まで読んでいただき、ありがとうございました。

[Envader](https://envader.plus/)って本当に便利だな〜。