シェルスクリプトとよく使うコマンドのメモ


# サンプルのシェルスクリプト

## 例1
引数で指定したCSVファイルの先頭行（見出し行）を削除し、他の行は2列目と3列目のみを順序を入れ替えて表示する。

```shell
#!/bin/bash

# 引数の数が 1 でなければエラーで終了する。
if [ $# -ne 1 ]; then
  echo "error: this command requires one argument." 1>&2
  echo "number of arguments passed: $#" 1>&2
  echo "usage: test01.sh infile" 1>&2
  return 1
fi

# 先頭行を削除し、他の行は2列目と3列目だけを抜き出して3列目、2列目の順で表示する。
sed 1,1d $1 | awk 'BEGIN {FS = ","; OFS = ",";} {print $3,$2;}'
```

### 解説
#### シェルスクリプト
<dl>
<dt>$#
<dd>引数の数を表すシェルスクリプトの変数
<dt>command 1>&2
<dd>command の標準出力への出力を標準エラー出力に統合する。ようは全部標準エラー出力に出す。
<dt>
</dl>

#### sed
<dl>
<dt>sed ＜N＞,＜M＞d
<dd>N行目からM行目を削除する（表示しない）。
</dl>

#### awk
<dl>
<dt>FS
<dd>Field Separator。入力データの区切り文字を指定するawkの変数。<br>
区切り文字はオプションの `-F<separator>` でも指定できる。
<dt>OFS
<dd>Output Field Separator。出力データの区切り文字を指定するawkの変数。
</dl>


## 例2：forループ
`echo "a"` を10回繰り返す。

```shell
for var in `seq 10`; do echo "a"; done
```

### 解説
- ```for var in `seq ＜回数＞`; do ＜コマンド＞; done```

＜コマンド＞を＜回数＞繰り返す。


## 例3：whileループ
2秒ごとに現在時刻を表示するのを5回繰り返す

```shell
#!/bin/bash

count=0
while [ $count -lt 5 ]
do
        echo -n $count" "; date +"%H:%M:%S"
        sleep 2
        let count++
done

exit 0
```

### 解説
- let 

四則演算、インクリメント、デクリメントなどができる。
`let var=1+2`
`let var--`


## 例4：forループその2
`ls *.txt` で返されるファイルに対して処理をを行う。

```shell
#!/bin/bash

files=`ls *.txt`
# files=("test01.txt" "test02a.txt" "test03b.txt")
for f in ${files[@]}
do
   echo ${f}
   cp ./${f} ./sub/
done
```

### 解説
- \`＜コマンド＞\`

コマンドの実行結果。
```files=`ls *.txt` ``` は `ls *.txt` の結果をfilesに代入している。

- files=("test01.txt" "test02a.txt" "test03b.txt")

配列の初期化。
lsの結果ではなく列挙したファイルに対して処理を行う場合はこの行を有効にする。

- files[@]

インデックス `@` で配列の全要素を参照する。



# よく使うコマンド

## grep
指定した文字列を含む行を表示する。

### オプション
|オプション　&nbsp; 　&nbsp; |説明|
|---|---|
|-e|正規表現|
|-E|拡張正規表現 ←こっち使った方が良さげ|
|-i|大文字小文字を区別しない|
|-w|単語としてマッチングを行う。|
|-c|マッチした数を表示（"wc -l" につなげなくてもこれだけで数を数えられる。）|
|-n|行番号をつけて表示|
|-l|ファイル名のみ表示|
|-L|パターンを含む行をまったく含まないファイルを表示する（-lの逆）|
|-C ＜n＞|マッチしたところから前後n行も表示|
|-P|パターンを Perl 互換の正規表現 (PCRE) として扱う。|
|-U|バイナリファイルとして扱う。CRキャラクターをstripしない。|
|-v|否定（マッチしなかった行を表示）|
|-z|データを改行文字ではなくnull文字で区切られたデータとして処理する。|

※注意："-ir" のようにしたら想定通り動かなかったので、オプションは1つずつ別個に書いた方がいい？

### OR
`grep -e 'aaa' -e 'bbb`
### AND
パイプを使う。
`grep -e 'aaa' <file> | grep -e 'bbb`

### サンプル
- `grep -lzUP '\r\n' *.txt`  
*.txtファイルの中で改行コードがCRLFのものを探す。

## sed
ストリーミングエディタ。

### オプション
|オプション　&nbsp; 　&nbsp; 　&nbsp; 　&nbsp; 　&nbsp; 　&nbsp; 　&nbsp; 　&nbsp; 　&nbsp; 　&nbsp; 　&nbsp; |説明|
|---|---|
|-e|処理内容を指定する。処理内容が1つだけなら省略可。|
|-i[＜サフィックス＞]|入力として指定したファイルを処理結果で上書き更新する。**サフィックスありの場合は入力ファイルにサフィックスをつけてバックアップを取ってから更新する。**|
|-r|拡張正規表現を使用する。正規表現を使うなら指定したおいたほうがよい？|

### サンプル
- `sed -e ＜I＞,＜J＞d -e ＜N＞,＜M＞d`
I～J行目とN～M行目を削除する。

- `sed -r /＜正規表現によるパターン＞/d`
正規表現にマッチした行を削除する。

- `sed -r 'N,M s/＜正規表現によるパターン＞/＜置換後の文字列＞/g`
N～M行目について、正規表現にマッチした部分を置換する。
行の指定を省略した場合はすべての行が対象となる。

## cut
test01.sh でawkを使っている部分は cut で近いことができる。
ただし、出力順の入れ替えはできない。
\#`-f2,1` としても1番目のフィールド、2番目のフィールドという順番で表示する。

### オプション
|オプション　&nbsp; 　&nbsp; 　&nbsp; |説明|
|---|---|
|`-d＜セパレータ＞`|フィールドを区切るセパレータを指定する。|
|`-f＜n＞,＜m＞`|n番目とm番目のフィールドを出力する。|
|`-f＜n＞-＜m＞`|n番目からm番目のフィールドを出力する。|

### サンプル
- `cut -d, -f2,3`<br>
CSV形式のデータの2列目、3列目を表示する。


# 参考ページ

## シェルスクリプト
[引数を処理する | UNIX & Linux コマンド・シェルスクリプト リファレンス](https://shellscript.sunone.me/parameter.html)
[Bashの入出力リダイレクトまとめ - Qiita](https://qiita.com/progrhyme/items/e99be732c2e62d4a7641)
[シェルの入出力制御あれこれ - Qiita](https://qiita.com/tag1216/items/7ce35b7c27d371165e56)
[いい加減覚えよう。 command > /dev/null 2>&1 の意味 - Qiita](https://qiita.com/ritukiii/items/b3d91e97b71ecd41d4ea)
[for 文の使用方法 | UNIX & Linux コマンド・シェルスクリプト リファレンス](https://shellscript.sunone.me/for.html)
[【初心者でもすぐわかる】シェルスクリプトwhileの使い方](https://eng-entrance.com/linux-shellscript-while)
[配列を使用する | UNIX & Linux コマンド・シェルスクリプト リファレンス](https://shellscript.sunone.me/array.html#全要素を参照する)

## grep
[Man page of GREP](https://linuxjm.osdn.jp/html/GNU_grep/man1/grep.1.html)
[grepでよく使うオプションの覚書(逆引き) – StupidDog's blog](https://stupiddog.jp/note/archives/734)
[Linuxコマンド【 grep 】パターンにマッチする行を表示 - Linux入門 - Webkaru](https://webkaru.net/linux/grep-command/)

## sed
[Man page of SED](https://linuxjm.osdn.jp/html/GNU_sed/man1/sed.1.html)
[sedでこういう時はどう書く? - Qiita](https://qiita.com/hirohiro77/items/7fe2f68781c41777e507)
[sed コマンド | コマンドの使い方(Linux) | hydroculのメモ](https://hydrocul.github.io/wiki/commands/sed.html)

## awk
[awkコマンドの基本 - Qiita](https://qiita.com/yamazon/items/563af1b485ff413d381f)
[https://qiita.com/hirohiro77/items/713d5bcf60fef7e88dfa](https://qiita.com/hirohiro77/items/713d5bcf60fef7e88dfa)
[共通テーマ: 実例でわかる awk: 第 1 回](https://www.ibm.com/developerworks/jp/linux/library/l-awk1/index.html)

## cut
[【 cut 】コマンド――行から固定長またはフィールド単位で切り出す：Linux基本コマンドTips（60） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1610/31/news026.html)