フロントエンドだろうが使えると徳を積めるShellコマンド

# 徳

**徳**

1. 精神の修養によってその身に得たすぐれた品性。人徳。
2. めぐみ。恩恵。神仏などの加護。
3. 得
4. 富。財産。
5. 生まれつき備わった能力・性質。天性。

[徳とは - コトバンク](https://kotobank.jp/word/%E5%BE%B3-104641)より

倫理学的には、正しい行為をさします。

## 徳

**陰徳あれば陽報あり**

中国の思想書「淮南子」の、「陰徳有る者は、必ず陽報有り」という一節からのことわざです。
人知れず良いことを行っていると、いずれ目に見える形で良い報いを得られる、という意味です。

## 徳

**徳を積む**

「良い行いを重ねておく」ことです。
前述のことわざから言えば、徳を積めば良いことがあるはずです。

## 徳

![劉備玄徳](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924363/bc40205a-8c7b-6415-957f-a786b962fa91.png)


姓は劉、名を備、字は玄徳。

彼は自分の息子に、「**これ賢これ徳、よく人を服す**」という言葉を遺しています。
聡明さと人への思いやりで、人は感服し、ついてくるという意味です。

更に彼は、「汝の父は徳が薄かった。この父に倣ってはならない。」と続けています。

謙虚すぎます。この一言で彼は非常に優れた人格者だったことが感じ取れます。
これぞ徳です。

## 徳を積みたい

あなたが劉備系フロントエンドエンジニアになりたいなら、1つの方法があります。
それは**Shellコマンドを打つこと**です。

フロントエンドだと黒画面にコマンドをﾊﾟｶﾊﾟｶうつシーンは少ないかもしれませんが、Shellは**業務効率化**に一役買います。
業務効率が向上すれば、売上が伸び**会社に利益**をもたらします。
また、周りの**エンジニアにも良い影響を与える**でしょう。

これすなわち<ins>**徳**</ins>です。

Shellを打って徳を積みましょう。

# やってみよう

さて、茶番はこの辺にして、本題に入ります。

## 事前準備

思い立ったらすぐコマンドを打てるように、ターミナルを即開けるようにしておきましょう。

GUI操作に慣れている方はショートカットを用意しておきます。
MacであればDockに追加しておきます。

できれば、ショートカットキーを設定すると良いです。MacはAutomatorで設定できます。

また、Visual Studio Codeであれば、ショートカットキーでターミナルを開くことが出来ます。
自分のMacの環境だと「control + Shift + `」で開けます。

このショートカットを手になじませましょう。

## `> file`: 実行結果をファイルに出力する

```shell
$ tree > list.txt
```

`コマンド > hoge.txt`で実行すると、左辺のコマンドの出力結果をhoge.txtに出力することができます。
後述のコマンドと合わせてお使いください。

## `grep`: 検索対象から正規表現に一致する行を検索し出力する

言わずとしれたテキスト検索コマンドです。
オプションがいろいろとあるのでここでは細かくは書き(たくあり)ません。
詳しい使い方はぜひググってお勉強してみてください。

私はしばしばパイプ(`|`)を伴って、コマンドの出力結果に対して検索します。

```shell
$ git log --oneline | grep -i build
709f0d7 build
546fb72 build
2f47554 build
```

上の例では、`git log`で出力されたコミットログから、"build"を含む行を出力しています。

`-i`オプションで大文字小文字を区別せず検索することができます。

例えば、HTMLファイルから使っている画像のパスを抽出したいときは以下のコマンドです。

```shell
grep -oE '\b\w+\.(jpg|png|webp|svg)\b' index.html | sort > hoge.txt
```

このようにして、書き出したhoge.txtと実際にある画像ファイルを見比べながら、不要な画像ファイルが含まれていないかを確認します。

更に、以下のコマンドで、リストアップした画像パスと実際のディレクトリの中を突き合わせて、画像が存在するかを確認できます。

```shell
ls -R /path/to/directory | grep -Ff hoge.txt
```

## `vim`: CLIのテキストエディタ Vimを起動する

:::note
お好きなCLIテキストエディタがあればそちらをお使いください
:::

**Vi**から派生したテキストエディタ**Vim**を起動します。
macOSには元々入っていると思いますが、Linux系のOSだとViしか入っていなかったりします。
利用する場合は、適宜インストールしてください。

私も使い倒すという程使ってはいませんが、数行書く程度であればささっと書けるので便利です。

操作が特殊と言われて敬遠されがちですが、ちょろっと書いて保存する程度ならそれほど覚えることはありません。
「その程度で使った気になるな」「単なるテキストエディタみたいな使い方するな」とVimmerに目をつけられそうですが、見逃してください。お願いします。お許しください。

覚えるといい操作はこんな感じです。

|キー|操作|
|:-|:-|
|:w|保存|
|:wq|保存して終了|
|:q!|保全せずに強制終了|
|i|挿入(insert)モードに移行|
|x|カーソル位置の文字を削除|
|dd|カーソル位置の行を削除|
|yy|カーソル位置の行をコピー|
|p|ペースト|
|w|次の単語に移動|
|b|前の単語に移動|
|h|カーソルを左に移動|
|j|カーソルを下へ移動|
|k|カーソルを上へ移動|
|l|カーソルを右へ移動|

```shell
$ vim hoge.txt
```

vimが起動したら、コマンド入力待機状態なので、`i`と入力すると挿入モードになります。
`-- INSERT --`と表示されるはずです。

この状態で書き書きしたら、Escapeキーで挿入モードを抜けて、`:wq`と打ってファイルを保存し終了します。
これで、カレントディレクトリにhoge.txtが作成されます。

もし、保存せずに戻りたいときは、`:q!`で終了できます。

## `ls`: ファイルやディレクトリの情報を表示する

「**そんなん使っとるわ**」と思われそうですが、いろいろオプションがあって奥が深いので、覚えておくと何かと便利です。
私がよく使うのは`ls -ahl`です。

### `-a`: 全てのファイルを表示する

隠しファイルも含めて全て表示させます。

```shell
$ ls -a
.  ..  .hoge a.txt b.jpg fuga/
```

### `-l`: ファイルの詳細を表示する

```shell
$ ls -l
-rwx------  1 user  group      96  7  7  2020 .hoge
-rw-r--r--  1 user  group     504 10 23 10:30 a.txt
-rwxrx-r--  1 user  group  590491 12  6  2021 b.jpg
drwx------  1 user  group     832  5 13 13:10 fuga/
```

左から、ファイルの種類1文字+パーミッション、ハードリンク数、所有者と所有グループ、ファイルサイズ、タイムスタンプ、ファイル・ディレクトリ名になります。

|項目|説明|
|:-|:-|
|-rwx------|ファイルの種類1文字+パーミッション|
|1|ハードリンク数（ファイルシステムの機能の一つ）|
|user  group|所有者・所有グループ|
|96|ファイルサイズ|
|7  7  2020|タイムスタンプ|
|.hoge|ファイル名|

### `-h`: ファイルサイズを分かりやすい単位で表示する

```shell
$ ls -lh
-rwx------  1 user  group   96B  7  7  2020 .hoge
-rw-r--r--  1 user  group  504B 10 23 10:30 a.txt
-rwxrx-r--  1 user  group  577K 12  6  2021 b.jpg
drwx------  1 user  group  832B  5 13 13:10 fuga/
```

### `-R`: 再帰的に表示する

下層のディレクトリまで表示してくれます。

## `pwd`: カレントディレクトリの絶対パスを表示する

今いるディレクトリのパスを表示します。オプションはありません。

```shell
$ pwd
/Users/hoge/Desktop
```

## `find`: ファイルの場所を検索する

ファイル名が分かっているときに、ファイルの場所を検索することができます。

そのファイルの絶対パスを取得したい時などに使ったりします。

```shell
$ find `pwd` -name index.html
/Users/hoge/fuga/about/index.html
/Users/hoge/fuga/csr/index.html
/Users/hoge/fuga/top/index.html
```

## `tree`: ツリー構造で一覧表示する

納品ファイル一覧を作る時などに便利です。

macOSのターミナルだと使えないので、Homebrewで導入します。

```shell
$ brew install tree
```

```shell
$ tree
.
├── assets
│   └── img
│       ├── image.jpg
│       └── image2.png
└── top
    └── index.html

3 directories, 3 files
```

`-L`オプションを付与して、数字を与えると、その数字の階層まで下がってツリー構造を出力してくれます。

```shell
$ tree -L 1
.
├── assets
└── top

2 directories, 0 files
```

## `git archive` & `git diff`: Gitリビジョン間の差分を抽出し出力する

`git diff`で差分ファイルをリストで取得し、`git archive`でディレクトリ構造を保ったままzipに出力します。

```shell
$ git archive <commit1> `git diff --name-only <commit1> <commit2> --diff-filter=ACMR` -o archive.zip
```

`<commit1>`と`<commit2>`にコミットID、タグを指定します。
`commit^`のように`^`（チルダ）をつけるとそのコミットの1個前、`^2`とすると2個前、のように指定することも可能です。
`HEAD`を指定することもできるので、最新のコミットから〜という指定もできます。

コミットIDは`git log --oneline`で参照できるので、こちらからコピペするのが良いでしょう。

<details>
<summary>オプションの説明</summary>

- `git diff`
  - `--name-only`: ファイル名のみ出力する
  - `--diff-filter`: 取得する差分をフィルタする
ACMRであれば、Added、Copied、Modified、Renamedを取得する
- `git archive`
  - `-o`: アーカイブファイル名を指定する
</details>

### Shellスクリプトを保存していつでも実行できるようにする

`vim`でShellスクリプトを書いて、いつでもarchiveを出力できるようにします。

```shell
$ vim export_diff.sh
```

```shell:export_diff.sh
#!/bin/sh
git archive $1 `git diff --name-only $1 $2 --diff-filter=ACMR` -o archive.zip
```

あとは実行する時にコミットID等を指定します。

```shell
$ export_diff.sh <commit1> <commit2>
```

# まとめ

自分が業務で使いがちなコマンドをまとめてみました。
他にも思い出したら追記していきたいと思います。

敬遠しがちな黒画面ですが、使いこなせれば効率アップが期待できます。
また、開発環境の構築時などどうしてもターミナルを見ないといけない場面があると思うので、このコマンドたちを思い出して使ってみてください。