UNIXコマンドチートシート

## はじめに

UNIXのコマンドについて少しだけ勉強したので、備忘録兼誰かの役に立てばと思い書きました。
今回は細かい説明などはせず、**チートシート**っぽい感じで書いています。
ですので、

- あの黒い画面で使うコマンドをいつも忘れちゃう…
- あんなことやこんなことできないの？

と思っている方はぜひご覧ください。一方、

- UNIXって何？おいしいの？
- 私はCUIじゃなくてGUI派なんです

という方のご期待にはそえないかもしれません。

また、コマンドのオプションも最低限しかのせていないので、詳しく知りたい方は、「man」で調べるか、ググってみてください。

まだ未熟者ですので、もし何か間違えているところや、「ここはこうした方がいいんじゃない？」というご意見がありましたら、何なりとおっしゃってくださいm(_ _)m

## 基本用語

#### カレントディレクトリ
自分が今いるディレクトリ（ざっくりとした表現です）

#### 親ディレクトリ
一つ上の階層のディレクトリ

#### ホームディレクトリ
ログインした直後にいるディレクトリ

## コマンドの基本

#### ディレクトリのあらわしかた

```
.  => カレントディレクトリ
.. => 親ディレクトリ
~  => ホームディレクトリ
../../ => 親ディレクトリの親ディレクトリ
```

#### 絶対パスと相対パス

絶対パスは

```
/home/user/aaa/bbb
```

みたいに書く（/から始まる）。
相対パスはカレントディレクトリがuserだとすると

```
aaa/bbb
```

みたいに書く(最初の / はつけない)。
ディレクトリやファイルを指定するときには、以下のようにこのどちらかで書く（基本は相対パス）。

```
ls /home/user/aaa/bbb
ls aaa/bbb
```
(lsについては後述)
以下では「dir」とか「file」って書いたりしていますが、すべてパス付きだと思ってください。

#### 空白の入力

コマンドラインでは空白をそのままでは入力できないので以下のようにします。

```
' '           # 空白一つ
'Hello world' # Hello world だと２つの文字列だと認識される
```

## ディレクトリの確認と移動

#### カレントディレクトリの確認
```
pwd
```

#### ディレクトリの中身の確認

```
ls                 # カレントディレクトリの中身を表示
ls dir             # ディレクトリを指定して中身を表示
ls -R              # ディレクトリ内のディレクトリ内の……中身も表示
ls -F              # 表示時にディレクトリなら / , ファイルなら * をつける
```
以上は組み合わせて使える

```
ls -RF dir
```
以下についても同様に組み合わせが可能

#### 指定したディレクトリに移動

```
cd dir        # 指定したディレクトリに移動
cd ..         # 親ディレクトリに移動
cd            # ホームディレクトリに移動
```

## ディレクトリの操作

#### ディレクトリの生成

```
mkdir dir
```

#### ディレクトリの削除

```
rmdir dir
```

#### ディレクトリのコピー（中身も）

```
cp -r src_dir dest_dir    # src_dirをコピーしてdest_dirにする
```

#### ディレクトリの移動

```
mv src_dir dest_dir        # src_dirをdest_dirに移動する
```

## ファイルの操作

#### ファイルの生成

```
touch file
```

#### ファイルの削除

```
rm file
```

#### ファイルのコピー

```
cp src_file file        #src_file を file としてコピー
cp src_file dir         #src_file を dir（ディレクトリ）にコピー（名前は変更しない）
```

#### ファイルの移動

```
mv src_file file        #src_file を file として移動
mv src_file dir         #src_file を dir（ディレクトリ）に移動（名前は変更しない）
```

## ファイルの中身の確認

#### ファイルの中身を表示

```
cat file
```

#### ファイルの中身を先頭の一部だけ表示

```
head file        # デフォルトは10行
head -n k file   # k行表示
```

#### ファイルの中身を後半の一部だけ表示

```
tail file        # デフォルトは10行
tail -n k file   # k行表示
tail -n +k file  # k行目から表示
```

## コマンドライン操作いろいろ（補完、履歴表示、マニュアル表示）

#### tabキーで補完

```
ls
a.out main.cpp

m tabキー → main.cpp
```

#### コマンドの使用履歴の表示

```
history    #何番目に実行されたかも表示される
```

#### コマンド履歴のn番目を再実行

```
!n
```

#### 入力したコマンドの、最新の使用履歴の内容（オプションなど）を再現して実行

```
!command
```

例

```
head -n 5 file

...          # head 以外のいろんなコマンド

!head    # head -n 5 file が実行
```

#### コマンドのマニュアル表示

```
man command

# man 操作中に
q   # マニュアル表示をやめる
h   # マニュアル表示中の操作のマニュアルを表示
```

## コマンドの機能拡張（パイプ, リダイレクト）

#### コマンドを結合 ( | をパイプという)

```
command1 | command2 | ...
```
※例は最後に

#### 出力結果をファイルに保存

```
command > file
```

#### 出力結果をファイルに追記（上書きしない）

```
command >> file
```

#### ファイルの内容をコマンドにわたす

```
command < file
```

## ワイルドカード

#### 0文字以上の任意の文字: *
例

```
head *.cpp
cat dir/*
```

#### 1文字の任意の文字: ?
例

```
ls dir_201?
cat file_????.txt
```

#### カッコ内の一文字: [...]
例

```
cat file201[89].txt   # file2018 か file2019
```

#### カッコ内のいずれかのパターン: {..., ...}
例

```
cat {*.txt, *.csv}   #csvファイルとテキストファイル
```

## 出力結果の操作

#### 列で区切って表示（区切り文字でフィールドに分けて、何番目のフィールドを表示するか指定する）

```
cut -f n -d , file       # 区切り文字を , として各行の n 番目を表示
cut -f 2-5,8 -d ' ' file   # これだと区切り文字を空白として2~5と8番目を表示
```

#### 文字列で検索してヒットした行を表示

```
grep string file  # file内の「string」を含む行を表示
# オプション
# -c: ヒットした行数のみ表示
# -h: 複数ファイル指定時にファイル名を表示しない（デフォルトでは表示）
# -i: 大文字小文字を区別しない
# -l: 文字列を含むファイルがあったら、そのファイル名のみ表示
# -n: ヒットした行の行番号も表示
# -v: マッチしなかった行を表示
```

#### 行でソートして表示（文字列として昇順でソート）

```
sort file
# オプション
# -n: 数字のソート
# -r: 降順にする
# -b: 先頭の空白を無視する
# -f: 大文字小文字を無視
```

#### 隣接している行が同じ内容なら削除して表示

```
uniq file
uniq -c file  # 隣接している行数をそれぞれ表示
```

#### 指定したフラグを基準に内容をカウント

```
wc -c file   # 文字数をカウント
wc -w file   # 単語数をカウント
wc -l file   # 行数をカウント
```

## 環境変数

#### 環境変数の一覧を表示

```
printenv
```

#### 特定の環境変数の中身を表示

```
echo $var    # varは環境変数
echo ${var}  # 上と同じ結果に
echo var     # これだと出力結果は「var」になる（$で中身参照）
```

#### 一時的な変数（シェル変数）の作成

```
var=...    # varは変数, ...は中身。
```

#### 環境変数の設定

```
export var        # varを環境変数にする（シェルを閉じても保存される）
export var=...    # varを作成して環境変数にするor既存の環境変数を更新

例
export PATH="${PATH}:path"  # パスを通す（PATHに追加したいパス（path）を追加）
```

#### 環境変数の削除

```
unset var
```

## for文

#### for文

```
for var in list
> do
> command1
> command2
...
> done

# 1行で書く場合
for var in list; do command1; command2; ...; done
```

#### 実行される順番

```
for v in 1 2 3; do echo $v; done
1
2
3

for v in 1 2 3; do echo $v; echo $v; done
1
1
2
2
3
3
```

#### listの例

```
1 2 3
*.txt      # a.txt, b.txt, c.txtがあったら *.txt と a.txt b.txt c.txt は同じ
var        # リストをあらかじめ変数に入れておいてもいい
```

## コマンドをファイルで実行

#### コマンドが書いてあるファイルを実行

```
bash file.sh                # 普通拡張子はshにする（しなくても動く）
bash file.sh arg1 arg2 ...  # arg1, arg2, ... は引数
```
※お使いの環境によっては動かないかも

#### 引数をうけとる

```
$@  # 引数のリスト
$n  # n番目の引数
``` 

#### コメントアウト

```
# ←これでコメントアウト
```

## パイプを使った応用例

※他のコマンドやオプションを使えばもっと短く記述できるものもあると思います。
こんなものもあるよ！とか、こう書いたら短いよ！とかあったら教えて下さい。

#### 行番号を指定してその行だけ取得

```
tail -n +k file | head -n 1    # fileのk行目を取得
```

#### 同じ内容の行の数をカウントして降順にする

```
sort file | uniq -c | sort -rn
```

#### 最近のコマンドの使用履歴を表示

```
history | tail -n 5
```

#### コマンドを指定して、そのコマンドを一番最近使ったときのオプション等を表示

```
history | grep "[0-9]  command " | tail -n 1    # commandのところを指定するコマンドにします。
```

## 参考

- [DataCamp](https://www.datacamp.com/) （ここで色々と学習中です。有料ですが優良です）
- [「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/index.html)
- [JM Project](https://linuxjm.osdn.jp/index.html)
- [とほほのWWW入門](http://www.tohoho-web.com/www.htm)
- [エンジニアの入り口](https://eng-entrance.com/)
- [UNIX&Linuxコマンド・シェルスクリプトリファレンス](https://shellscript.sunone.me/)