【linux】コマンド・知識

linuxコマンドを学習して、使えそうだと思ったもの・忘れないようにしたいものを備忘録として抜粋。
その都度更新していく予定。

# 索引
- [コマンド](#コマンド)
 - [less(ファイルの中身を見る)](#less)
     - [スクロール](#スクロール) / [検索](#検索)
 - [touch(空のファイルを作成)](#touch)
 - [diff(差分比較)](#diff差分比較)
 - [sed(テキストの置換処理)](#sedテキストの置換処理)
     - [後方参照](#後方参照)
     - [特定の文字列を含む行を削除する](#特定の文字列を含む行を削除する)
     - [置換後のファイルを上書き保存する](#置換後のファイルを上書き保存する)
 - [cut(テキストの切り出し)](#cutテキストの切り出し)
     - [範囲指定&区切り文字変更](#範囲指定区切り文字変更)
 - [tar(アーカイブの作成、圧縮)](#tarアーカイブの作成圧縮)
- [知識](#知識)
 - [>(リダイレクト)](#リダイレクト)
     - [ファイルディスクリプタ(入出力の番号)](#ファイルディスクリプタ入出力の番号)
 - [/dev/null](#devnull)
 - [パーミッション](#パーミッション)
     - [実行権の付与](#実行権の付与)

# コマンド
## less
- 中身が長いファイルの中身を見る時に使う。
- ファイルの中身を見る時にスクロール操作や検索ができる。

### スクロール
|コマンド|動作|
|:---:|:---:|
|スペースキー<br>もしくは<br>f|１画面分下にスクロール|
|b|１画面分下にスクロール|
|j|1行下にスクロール|
|k|1行上にスクロール|
|g|ファイルの先頭に移動|
|G|ファイルの末尾に移動|

### 検索
|コマンド|動作|
|:---:|:---:|
|/<文字列>|<文字列>を上から下方向に検索|
|?<文字列>|<文字列>を下から上方向に検索|
|n|次の検索結果に移動|
|N|前の検索結果に移動|

## touch
- 本来はファイルのタイムスタンプを更新・変更するコマンド。
- ファイルが存在しない時は、空のファイルを作成する。
 - ファイルが存在する時はタイムスタンプを更新するので、**中身のあるファイルを誤って上書きしてしまう心配がない。**

## diff(差分比較)
- ファイル同士の差分を表示するコマンド。

```
$ cat sample1.csv
カラム1,カラム2,カラム3
1,2,3
a,b,c
あ,い,う
$ cat sample2.csv
カラム1,カラム2,カラム3
1,2,3
d,e,f
あ,い,う
$ diff sample1.csv sample2.csv
3c3
< a,b,c
---
> d,e,f
```

- 試しに上のcsvファイルから差分を表示し、もともとのヘッダー(カラム行)も先頭に追加してみる。

```bash
$ diff sample1.csv sample2.csv | grep -E "^>" | sed -e 's/^> //g' | sed "1 i `head -n 1 sample1.csv`"
カラム1,カラム2,カラム3
d,e,f
```
|コマンド|動作|
|:---:|:---:|
|grep -E "^>"|先頭が`>`の行のみを抽出|
|sed -e 's/^> //g'|先頭の`>`を削除|
|sed "1 i <テキスト>"|<テキスト>を1行目に挿入|
|head -n 1 sample1.csv|sample1.csvの1行目|

## sed(テキストの置換処理)
- テキストファイルを編集するスクリプト言語。
- 置換処理には`-e`オプションを指定する。(省略可)

```bash
$ cat sample2.csv
カラム1,カラム2,カラム3
1,2,3
d,e,f
あ,い,う
$ sed -e 's/d,e,f/a,b,c/g' sample2.csv
カラム1,カラム2,カラム3
1,2,3
a,b,c
あ,い,う

# 上の書き方だとsample2.csvは上書きされていない
$ cat sample2.csv
カラム1,カラム2,カラム3
1,2,3
d,e,f
あ,い,う
```

【参考記事】
[bioinformatics(sed)](https://bi.biopapyrus.jp/os/linux/sed.html)
[sedコマンドの備忘録](https://qiita.com/takech9203/items/b96eff5773ce9d9cc9b3)

### 後方参照
- 置換前の文字列を置換後の部分でも使いたいとき。
- csvから特定のカラムを取り出してみる。

```bash
$ cat sample.csv
name,age,address,job
佐藤,30,東京都,教師
加藤,18,神奈川県,学生
五十嵐,25,埼玉県,医師
$ sed -e "s/\(.*\),\(.*\),\(.*\),\(.*\)/\1,\3,\4/g" sample.csv
name,address,job
佐藤,東京都,教師
加藤,神奈川県,学生
五十嵐,埼玉県,医師
```

### 特定の文字列を含む行を削除する
```
$ sed '/^佐藤/d' sample.csv
name,age,address,job
加藤,18,神奈川県,学生
五十嵐,25,埼玉県,医師
```
先頭に「佐藤」が含まれる行を削除した。

【参考記事】
[sedで指定した行の削除をする方法(サンプルコードあり)](https://it-ojisan.tokyo/sed-d/)

### 置換後のファイルを上書き保存する
- iオプションで上書き保存ができる。

上で記述した削除の場合で考えてみる。

```bash
$ sed '/^佐藤/d' sample.csv
name,age,address,job
加藤,18,神奈川県,学生
五十嵐,25,埼玉県,医師
# これだと上書きされていない
$ cat sample.csv
name,age,address,job
佐藤,30,東京都,教師
加藤,18,神奈川県,学生
五十嵐,25,埼玉県,医師
$ sed -i '/^佐藤/d' sample.csv
$ cat sample.csv
name,age,address,job
加藤,18,神奈川県,学生
五十嵐,25,埼玉県,医師
```

【参考記事】
[sedで置換してファイルを上書きする](https://it-ojisan.tokyo/sed-replace-overwrite/)

## cut(テキストの切り出し)
- 今回は、テキストの行から固定長またはフィールド単位で指定した部分だけを切り出す。
- デフォルトの区切り文字はタブ。

### 範囲指定&区切り文字変更
```bash
cut -d ',' -f 3-8 sample.csv
```
- `-d ','`で区切り文字をカンマに変更
- `-f 3-8`で3番目から8番目のテキストを切り出す
 - `-f 3,8`とすると、3番目と8番目のみを切り出す

【参考記事】
[【 cut 】コマンド――行から固定長またはフィールド単位で切り出す](https://www.atmarkit.co.jp/ait/articles/1610/31/news026.html)

## tar(アーカイブの作成、圧縮)
- 複数ファイルからアーカイブを作成するコマンド。
- 詳細は別の記事に記載。
編集中

# 知識
## リダイレクト
- 入出力先を変更する機能。

### ファイルディスクリプタ(入出力の番号)
- 標準入出力にはそれぞれファイルディスクリプタという番号が振られており、これらの番号はリダイレクトでよく使用される。

|ファイルディスクリプタ|入出力|
|:---:|:---:|
|0|標準入力|
|1|標準出力|
|2|標準エラー出力|

#### 入力のリダイレクト
ファイルから入力する機能

```bash
$ cat < /etc/hosts
127.0.0.1   localhost
::1         localhost
```

#### 出力のリダイレクト
コマンドの実行結果を画面に表示せずに、ファイルに保存する。

```bash
$ ls work
abc.txt  hoge  test
$ ls work > output.txt
$ cat output.txt
abc.txt
hoge
test
```
- `コマンド > 出力ファイル`の形。
- 出力ファイルがない場合に実行しても、自動的にファイルは作成される。

#### エラー出力のリダイレクト
エラーの内容を画面に表示せずに、ファイルに保存する。

```bash
$ ls hoge
ls: hoge にアクセスできません: そのようなファイルやディレクトリはありません
$ ls hoge 2> error.txt
$ cat error.txt 
ls: hoge にアクセスできません: そのようなファイルやディレクトリはありません
```
- `コマンド 2> 出力ファイル`の形。

#### 標準出力とエラー出力をまとめる
```bash
$ ls / hoge > output.txt 2>&1
$ cat output.txt 
ls: hoge にアクセスできません: そのようなファイルやディレクトリはありません
/:
bin
boot
dev
etc
home
```
- `コマンド 2> 出力ファイル 2>&1`の形。

#### リダイレクトによる追記
- `>`は同じファイルを指定した場合、上書きされる。
- `>>`は上書きではなく追記される。

```bash
$ echo one > output.txt
$ cat output.txt 
one
$ echo two >> output.txt
$ cat output.txt 
one
two
```

【参考記事】
[５分で一通り理解できる！Linuxのリダイレクト 使い方と種類まとめ](https://eng-entrance.com/linux-redirect)

## /dev/null
- 入力先に指定したところで何も返されないし、出力先に指定してもデータは消えて何も表示されない。
- 1つ目の参考記事の例えがわかりやすいと思います。
 
> ブラックホールなファイル。
> 吸いこむことはあっても吐き出すことはありません。 

使われるケースとして多いのは、出力を表示したくない時

```bash
hoge.sh > /dev/null
```
これだとエラー出力は普通に表示されてしまうそうなので、エラー出力も捨ててしまいたい場合は、以下のように書きます。(bashの場合)

```bash
hoge.sh > /dev/null 2 > &1
```

【参考記事】
[/dev/nullとは | 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word11733.html)
[【Linux】/dev/nullをエンジニアが使う２つの目的](https://lanchesters.site/linux-dev-null/)
[Linux、「/dev/null」とはなんぞや？](http://piyopiyocs.blog115.fc2.com/blog-entry-664.html)

## パーミッション
- フォルダやファイルに対するアクセス権・権限のこと。
- 3つの実行権と3つの所有権がある。
- つまりは、「誰」が「どのような権限」を持っているかを定めたもの。

|所有権|
|:---:|
|自分(Owner)|
|グループ(Group)|
|その他(Other)|

|実行権|記号|
|:---:|:---:|
|読み|r|
|書き|w|
|実行|x|

例えば、以下のようにシェルの「許可がありません」と言われた時

```bash
$ cat test.sh 
echo "abcde"
$ ./test.sh
-bash: ./test.sh: 許可がありません
$ ls -l test.sh 
-rw-r--r--. 1 root root 0 10月  6 03:04 test.sh
```

<table border="1">
<tr>
  <th>ファイル<br>タイプ</th>
  <th colspan=3>オーナー</th>
  <th colspan=3>グループ</th>
  <th colspan=3>その他</th>
</tr>
<tr>
  <td>-</td>
  <td>r</td>
  <td>w</td>
  <td>-</td>
  <td>r</td>
  <td>-</td>
  <td>-</td>
  <td>r</td>
  <td>-</td>
  <td>-</td>
</tr>
</table>

このように、シェルの実行権(x)がないことがわかる。

### 実行権の付与
上記のように実行権がなかったときは`chmod`コマンドで追加する。

```bash
$ chmod u+x test.sh
$ ./test.sh
abcde
$ ls -l test.sh 
-rwxr--r--. 1 root root 13 10月  6 03:53 test.sh
```

|記号|意味|
|:---:|:---:|
|u|自分に対して|
|+|権限を追加|
|x|実行権|

【参考記事】
[パーミッション | 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word1169.html)
[パーミッションについて](http://web.tku.ac.jp/~densan/local/permission/permission.htm)
[ファイルのパーミッションと属性](https://wiki.archlinux.jp/index.php/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E5%B1%9E%E6%80%A7)