Webエンジニアが入社2年目までに習得したコマンド



この記事は[ニフティグループ Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nifty) の2日目の記事です。

昨日は [@motaHack](https://qiita.com/motaHack) さんで「[文系卒がふつうに企画職になる前にWEBのエンジニアをやってみた感想](https://motahack.hatenablog.jp/entry/2020/12/01/211746)」でした。先輩が文系卒だったと知ってビックリしました。情報系卒の私でさえ、入社後は学びの連続に感じましたが、学ぶことの量は先輩の比にならないと思いました。先輩が残して下さったわかりやすい資料のおかげでいつも助かってます！

# はじめに

学生時代は、サーバにログインしてコマンドを使う機会はほとんどありませんでした。

しかし、Webエンジニアとして会社で仕事を始めると、一転して、毎日のようにサーバにログインして、様々なコマンドを使うようになり、たくさんのコマンドを学ぶことが多かったです。

そこで今回は、この２年間で学んだコマンドと、のうち便利だと思ったコマンドを紹介しようと思います。

# 入社前に知っていたコマンド

```text:講義
ls cd pwd touch mkdir cp mv rm chmod
curl ifconfig ping javac java psql
```

```text:研究、個人開発
brew vim git docker node npm rails heroku
```
たしかこの程度だったと思います。
いつも、Finder と VSCode/IDE を使っていたので、lsなどコマンドも滅多に使う機会がなく、
Vimに関しては、Gitで競合が起きた時のコミットメッセージを入力する時くらいしか使っていませんでした。

# 新卒研修で知ったコマンド

入社後は１ヶ月間の技術研修がありましたが、そのうち2日間くらいは、Linuxの基礎について体型的に学びました。

```text:コマンド
su who useradd passwd
find grep diff ln
top ps jobs date netstat df du tty
yum apt-get export which xargs tee
```
このうち、今でもよく使うのは、`su` `grep` `find` `diff` `date`です。

```text:記法
| ・・・ パイプライン
> >> ・・・ リダイレクション
; & && || ・・・ リスト演算子
? * ワイルドカード
# ・・・ コメント
```
このときは、たったの2日間ですごい成長を感じました。特に、存在を知らなかった記法があると知って、ワクワクしました。

# 配属後に知ったコマンド

一覧を以下に載せます。

```text:コマンド
ssh crontab tmux head tail stat nkf awk jq cut sort uniq nl readlink wc sdiff
sed zip unzip tar scp sftp wget
pgrep nslookup ip printenv env set chkconfig
sh at nohup watch timeout time sleep expr let test eval md5sum aws sam
```

このうちよく使うのは、`ssh` `crontab` `scp` `awk` `nkf` `tail` `tmux` です。
※ 一部漏れているものもあると思います、ご容赦ください。

```text:記法
{1..3} {1,2,5} ・・・ ブレース展開
>&1 >&2 ・・・ 標準出力のみ、エラー出力のみのリダイレクト
```
このうち、知っていると便利だと思った記法とコマンドをいくつか紹介したいと思います。

## 便利な記法
とても便利な `> >>` リダイレクションと `|` パイプラインについては、
使う機会が多いので、知っている人が多いと思うので割愛します！

### `\` 改行
```bash
$ somecommand \
  --optionA=xxxx \
  --optionB=yyyy \
  --optionC=zzzz \
  --optionD=wwww
```
長いコマンドを資料に書く時によく使います。

### `?` `*` ワイルドカード
たくさんの似たファイルを処理する場合によく使います。

`?` = 任意の一文字

```shell
$ ls hoge?.txt
hoge1.txt
hoge2.txt
```
`*` = 任意の文字数

```shell
$ ls hoge*.txt
hoge1.txt
hoge2.txt
hoge123.txt
```

### `{1..3}` `{1,3,5}` ブレース展開
```shell
$ echo hoge{1..3}
hoge1 hoge2 hoge3
```
```shell
$ touch hoge{1,3,5}.txt
$ ls
hoge1.txt hoge3.txt hoge5.txt
```

### `` `コマンド` `` `$(コマンド)` コマンド置換
`` ` `` バッククオートでコマンドを囲むと、コマンドの実行結果（標準出力）と置換されます。

```
$ touch file.`date +%Y-%m-%d`.txt
$ ls
file.2020-12-01.txt
```
`touch file.$(date +%Y-%m-%d).txt`でも同じ

### `;` `&&` `||` リスト演算子
```
コマンド1 ;  コマンド2  # コマンドが終わり次第コマンド2を実行
コマンド1 &  コマンド2  # コマンド1をバックグランドで実行し、コマンド2を同時実行
コマンド1 && コマンド2  # コマンド1が正常終了だった場合のみコマンド2を実行
コマンド1 || コマンド2  # コマンド1がエラー終了だった場合のみコマンド2を実行
```

### `-abc` オプションの連結
この2つは同じ

```bash
tar -x -z -v -f data.gz
tar -xzvf data.gz
```

## 調査に便利なコマンド

### find
特定のディレクトリ配下の全箇所でファイルを探す

```
find dirname -type f -name filename
```

### sdiff

diff はちょっと見づらいと思ったことはありませんか？

```
$ diff file1 file2
2d1
< bbb
3a3
> ddd
```
sdiffは、diffと違って左右で見比べることが出きて、見やすいのでよく使ってます。

```
$ sdiff file1 file2
aaa								aaa
bbb							  <
ccc								ccc
							  >	ddd
```
ちなみに、 `diff -y` `diff --side-by-side`でも代用可能です。

### pgrep
バッチなど、あるコマンドのプロセスが実行中かどうか確認

```
$ pgrep -l 'hoge.sh foo bar'
3903 hoge.sh foo bar
```
`$ ps | grep 'hoge.sh foo bar' -v grep` より簡潔で便利です

### watch
コマンドを3秒ごとに実行

```
$ watch -n 3 ls -ltr
```
タスクファイルや、ロックファイルなどの消化状況をリアルタイムで見たい時に便利です。

### time
コマンドの実行にかかった時間を最後に出力する

```
$ time コマンド
```

### tmux
画面分割して複数台のサーバに同時にログイン（SSH接続）するためのコマンドです。
冗長構成となっているサーバ（web001, web002, ...）などで同じコマンドを叩くときに大変便利で、リリース時によく使います。
※ 標準コマンドではないので、インストールする必要があります。
使い方がやや複雑なので、ここでは割愛して、紹介だけにします。 :bow:

## ファイルを見る時に便利なコマンド
業務ではサーバに入ってログファイルやデータCSVなどを確認する機会がたくさんありますので、
その時に使うと便利なコマンドです。
ちなみに、ここにあるコマンドは全て、 `|` パイプラインで連結することができます。

### tail
ファイルの最後の10行のみを出力する (逆の、`head` もあります)

```
tail file.log
```
最後の3行のみ表示

```
tail -3 file.log
```
`-f` オプションをつけると、ファイルに更新があった場合、新しい行がリアルタイムで表示します。アクセスログなどを見る時によく使います。 (Ctrl+Cで抜ける)

```
tail -f file.log
```

### wc
行数カウント

```
wc -l filename
```
`wc: word count` `-l: line`

### nl
行願号も出力 (number of line)

```
nl hoge.xt
   1  aa
   2  bb
```

### sed
10行目のみ表示

```
$ sed -n 10p file
```
10-20行目を表示する

```
$ sed -n 10,20p file
```

### cut
tsvの1カラム目だけ出力する

```
$ cut -f 1 file.tsv
```
csvの1カラム目と3カラム目だけ出力する

```
$ cut -d ',' -f 1,3 file.csv
```

### awk
エディタを使わず、コマンドだけでテキストファイルを編集できるとてもパワフルなコマンドです。
CSVファイルの確認・集計にも活用でき、どうちらかというと、この用途で使うことの方が多いです。

例えば、以下の例でCSVの1行目のカラムの数を確認出来きます

```
$ head -1 sample.csv | awk -F ',' '{print NF}'
```
また、以下の例でTSVのカラム数のごとの行数を確認できます

```
$ awk '
  { arr[NF]++ }
  END{
   for(i = 1; i<length(arr); i++){
     print i "カラム:", arr[i] "行"
    }
  }
' data.csv
```
```
1カラム: 13行
2カラム: 66行
3カラム: 21行
```
awkコマンドは、自分が知っているコマンドの中でも、特に奥が深く、様々なことができるコマンドとなっております。awkを極めるものは、シェル芸を極める。

### nkf
文字化けするファイルの中身を文字化けさせないで表示

```
$ nkf -w　mojibake.txt
```
`-w` : UTF-8に変換
network kanji filterの略らしい
標準コマンドではないでインストールが必要ですが、よく使います

## その他、よく使うコマンド

### バックアップをとる
よくブレース展開、コマンド置換、dateコマンドを組み合わせて使います。

```
$ ls
file.txt
$ cp -p file{,.`date +%Y-%m-%d`}.txt
$ ls
file.txt   file.2020-12-01.txt
```
`-p` : ファイルの権限設定(例:rwxr--r--) を維持する

### scp
サーバ間でファイルをコピーするときに使います

```
$ scp -p user@host:/元ファイル 先ディレクトリ
```


### 置換 
あるファイルの中 apple を全て APPLE に置換する

```
$ sed -ie "s/apple/APPLE/g" sample.txt
```
`-i`, `--in-place` 結果を標準出力せずにファイルを置き換える
`-e`, `--editing` : 置換内容
`s`:正規表現で置換処理
`g`: 一行のみでなく、全ての行を置換

実は、　sed も　awk と同じで、コマンドでテキストファイルを編集することができます。
awk に比べて、できることが少ない分、少ない記法で編集できるので、置換の時によく使います。

### at
指定時間にコマンドを実行

```
$ at 11:30 20102020
at> touch hoge
at> ctrl + D
job 4 at Tue Oct 20 11:30:00 2020
```

# 最後に
いかがでしたでしょうか？
もし、一つでも新しい発見があれば嬉しいです。

本日 12/2 は、 [AWS re:Invent](https://aws.amazon.com/jp/about-aws/events/2020/reinvent/) ですね！
どんな発表がされるか楽しみです。

# 次回予告
さぁ、明日の記事は、なんと、**現在未定**のようです！
果たして、たすきを繋ぐ者は現れるのでしょうか？　注目です。

[ニフティグループ Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nifty)