よく使うシェルコマンドのメモ

どの環境でも使えるかは不明。覚える気がないので自分用のメモとして残す。
主にワンライナーで利用するので移植性などは気にしてない。
できなければ別の方法を使うだけ。
随時追加。

正規表現を可視化するサービス
https://regexper.com/
https://regexr.com/

## sed

```bash
# ()で囲った部分は\1とかで抜き出して使える
$ echo 0123456789 |sed "s/^\(....\)\(...\)\(...\)/\1-\2-\3/g"
0123-456-789

$ echo 0123456789 |sed "s/^\([0-9]\{4\}\)\([0-9]\{3\}\)\([0-9]\{3\}\)/\1-\2-\3/g"
0123-456-789
```

### sed 1文字ずつ変換

```bash
# aをA,bをB,dをsに変換する。
$  echo {a..d} |sed "y/abd/ABs/"
A B c s
```

### sedで\nを改行する

[めちゃイケてる。。尊敬](https://qiita.com/richmikan@github/items/3c74212b0d8dec9bd00f)

```bash
$ LF=$(printf '\\\012_')
$ LF=${LF%_}
$ echo "hogehoge\nfoo\nbar" | sed 's/\\n/'"$LF"'/g'
```

### sedで改行を挟んで置換する、更に置換後にも改行を入れる

```bash
$ LF=$(printf '\\\012_')
$ LF=${LF%_}

$ echo "aa AA,bb BB,cc CC" |tr "," "\n" 
aa AA
bb BB
cc CC

$ echo "aa AA,bb BB,cc CC" |tr "," "\n" |sed '/A/N;s/AA\nbb/AA'"${LF}"'XX/'
aa AA
XX BB
cc CC
```

### マッチした行から次のマッチした行までを抜き出す

```bash
seq 9 |sed -n -e '/3/,/8/p'
3
4
5
6
7
8
```

### 特定行を削除

```bash
$ seq 3 |sed '1d'
2
3
```

## grep

### 1文字ごとに改行

```bash
$ echo abcd |grep -o "."
a
b
c
d
```

### 行番号つける

```bash
$ grep -n "." a
1:a
2:b
3:c
4:d
5:e
6:f
```

## echo

### エスケープ文字解釈

```bash
$ echo -e "a\nb"
a
b
```

### 進数

```bash
$ echo $((10+10))   # 10進数の10たす10進数の10
20
$ echo $((10+010))  # 10進数の10たす8進数の10 
18
$ echo $((10+0x10)) # 10進数の10たす16進数の10
26
```

## cat

### 制御コードを表示

```bash
$ cat -e file
a$
b$
c$
d$
e$
f$
```

## uniq

### 集計  `sort|uniq -c`

```bash
$ seq 3 |sed p |sort |uniq -c`
   #重複数 文字列
   2 1
   2 2
   2 3
```

## xargs

### 

```bash
$ seq 9 |xargs -n 3
1 2 3
4 5 6
7 8 9
```

## awk

### 大文字/小文字に変換

```bash
$ echo "ABCdefg" |awk '{a=toupper($0);print a}'
ABCDEFG
```

### $1が同じ行の$2をまとめる

```bash
$ echo "a 1,b 4,a 2,a 3,b 5"|tr "," "\n"
a 1
b 4
a 2
a 3
b 5

$ echo "a 1,b 4,a 2,a 3,b 5"|tr "," "\n" |awk '{D[$1]=D[$1]" "$2}END{for(i in D){print i D[i]}}'`
a 1 2 3
b 4 5
```

### 列数カウント

```bash
$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z

$ echo {a..z}|awk 'z=split($0,word," "){print z}'
26
```

### 文字列を含むか検索

```bash
$ echo -e "ABC\ndefg\nAB" |awk '{a=match($0,/AB/);print a}'
1
0
1
```

### 検索に一致した次の行を取り出す

```bash
$ echo ab1cdef1g |grep -o "." |awk '/1/{getline ;print $0}'
c
g
```

### 数学的な計算

```bash
#exp
#int
#log
#sin
#sqrt
#atan2
#rand
#srand
$ echo "2" |awk '{print cos($1)}'
-0.416147
```

### 置換

```bash
# gsubはグローバル <-> sub
$ echo "abc" |awk '{a=gsub(/a/,"A",$0);print $0}'
Abc
```

### indexを返す

```bash
$ echo "abcdefg" |awk '{a=index($0,"d");print a}'
4
```

### BEGINと変数

```bash
$ echo a b c d|awk 'BEGIN{one=1;two=2}{print $(one + two)}'
c
```

### FS,RS,NR,NF

```bash
# FS=システム変数,フィールドセパレータ
$ echo -e "aawfa\te,awf" |awk  'BEGIN{FS = "[,\t]"}{print $2}'
e

# RS=レコードセパレータ
echo {1..10} |awk '{print $0RS"b"}'
1 2 3 4 5 6 7 8 9 10
b

# NR
$ echo {1..10}|sed "s/ /\n/g" |awk '{print NR":",$0"$"}'
1: 1$
2: 2$
3: 3$
4: 4$
5: 5$
6: 6$
7: 7$
8: 8$
9: 9$
10: 10$

# NF 列数が2のものだけ抜き出す
echo "0,1 1,2 2,3,4,5 5"|tr "," "\n" |awk 'NF==2{print $0}'
1 1
2 2
5 5
```

### 位置揃え

```bash
# printf
# c.ascii文字
# d.10進数
# i.10進整数POSIX
# e.浮動小数点 小文字
# E.同上 大文字
# f.上
# g.e or f と同じで末尾0非表示
# G.E or f ...
# o.無符号8進数
# s.文字列
# x.無符号16進数 小文字
# X.同上 大文字
# %.リテラルの%
$ echo {a..c}{0..3} |tr ' ' '\n' |awk '$1 ~ /c/ || $1 ~ /0/{printf "|%10s|\n", $1}'
|        a0|
|        b0|
|        c0|
|        c1|
|        c2|
|        c3|

$ $ echo {a..c}{0..3} |sed "s/ /\n/g" |awk '$1 ~ /c/ || $1 ~ /0/{printf "|%-10s|\n", $1}'
|a0        |
|b0        |
|c0        |
|c1        |
|c2        |
|c3        |
```

### substr指定以降の文字列を返す

```bash
$ echo "abcdefg" |awk '{a=substr($0,4);print a}'
defg
```

### 文字数カウント

```bash
$ echo "abcdefg" |awk '{a=length($0);print a}'
7
```

## sort

### 引数なし

```bash
$ cat test
1:2.0:1e+10:a
2:3.0:2e+11:b
2:1.0:3e+13:d
3:2.0:1e+10:f
3:6.0:6e+18:g
2:2.0:2e+13:c
3:1.0:7e+12:h
4:9.0:9e+14:i
10:0.0:1e-12:x
10:0.0:1e-11:y
11:0.0:1e+11:z
2:4.0:4e+14:e
5:8.0:1e+20:k

$ sort test
10:0.0:1e-11:y # キャラクタとみなすので先頭の10が一番初めにくる
10:0.0:1e-12:x
11:0.0:1e+11:z
1:2.0:1e+10:a
2:1.0:3e+13:d
2:2.0:2e+13:c
2:3.0:2e+11:b
2:4.0:4e+14:e
3:1.0:7e+12:h
3:2.0:1e+10:f
3:6.0:6e+18:g
4:9.0:9e+14:i
5:8.0:1e+20:k
```

### `-n` 数値

```bash
$ sort -n test
1:2.0:1e+10:a #数値で並ぶので1が初めにくる
2:1.0:3e+13:d
2:2.0:2e+13:c
2:3.0:2e+11:b
2:4.0:4e+14:e
3:1.0:7e+12:h
3:2.0:1e+10:f
3:6.0:6e+18:g
4:9.0:9e+14:i
5:8.0:1e+20:k
10:0.0:1e-11:y
10:0.0:1e-12:x
11:0.0:1e+11:z
```

### `-g`,`-r`,`-k`など色々入り

```bash
# 引数説明
-t:       セパレータを:にする。
-k 2n,2:  数値(n)として2列目を昇順ソート。SQLのorder byと同じ感じで第1ソートする。
-k 3gr,3: 浮動小数点の理工学的な記法 (`1.0e-34' や `10e100' など)を含めて、
          (g)3列目を降順(r)ソート。
          gオプションは遅いしあまり使わないほうがいいらしい。
-k 1rn,1: 数値として1列目の降順ソート。
-b:       変なスペースが入っていてソートがおかしくなるのを防ぐ。
          consider only printable characters(from man)
```

```bash
$ sort -b -t : -k 2n,2 -k 3gr,3 -k 1rn,1 test
11:0.0:1e+11:z
10:0.0:1e-11:y
10:0.0:1e-12:x
2:1.0:3e+13:d
3:1.0:7e+12:h
2:2.0:2e+13:c
3:2.0:1e+10:f
1:2.0:1e+10:a
2:3.0:2e+11:b
2:4.0:4e+14:e
3:6.0:6e+18:g
5:8.0:1e+20:k
4:9.0:9e+14:i
```

## 使えそうかもしれないけど使ったことない

### rev 文字列反転

```bash
$ echo {1..10} |rev
01 9 8 7 6 5 4 3 2 1
```

### nl 行番号つける

```bash
$ nl file
     1	0123456789
```

### vimdiffぽいdiff出力
```
$ cat a.txt b.txt
10.00~10.90 4229    0.08    04229   0.08
10.90~11.80 4256    0.09    08485   0.17
11.80~12.70 4108    0.08    12593   0.25
12.70~13.60 4244    0.08    16837   0.34
13.60~14.50 4235    0.08    21072   0.42
14.50~15.40 4141    0.08    25213   0.50
15.40~16.30 4172    0.08    29385   0.59
10.00~10.90 4229    0.08    04229   0.08
10.90~11.80 4256    0.09    08485   0.17
11.80~12.70 4108    0.08    12593   0.25
12.70~13.60 4244    0.08    16837   0.34
13.60~14.50 4235    0.08    21072   0.42
14.50~15.40 4141    0.08    25213   0.50
15.40~16.30 4172    0.08    29384   0.59
```

```
$ diff -ybd --width=120 --suppress-common-lines {a,b}.txt
15.40~16.30 4172    0.08    29385   0.59                   |    15.40~16.30 4172    0.08    29384   0.59

$ diff --side-by-side a.txt b.txt
10.00~10.90 4229    0.08    04229   0.08                        10.00~10.90 4229    0.08    04229   0.08
10.90~11.80 4256    0.09    08485   0.17                        10.90~11.80 4256    0.09    08485   0.17
11.80~12.70 4108    0.08    12593   0.25                        11.80~12.70 4108    0.08    12593   0.25
12.70~13.60 4244    0.08    16837   0.34                        12.70~13.60 4244    0.08    16837   0.34
13.60~14.50 4235    0.08    21072   0.42                        13.60~14.50 4235    0.08    21072   0.42
14.50~15.40 4141    0.08    25213   0.50                        14.50~15.40 4141    0.08    25213   0.50
15.40~16.30 4172    0.08    29385   0.59                      | 15.40~16.30 4172    0.08    29384   0.59

```

### n番目以降の引数を取得

N番目以降、M個の引数を取得したいときは、${@:N:M}

### yes

続行するために”y”を入力し、
Enterキーを押す必要があるようなプログラムをインストールするときにyesを使える。

```
$ yes |sudo yum install pv
```

### pipe viewer

```
$ sleep 100 |pv
   0 B 0:00:01 [   0 B/s] [<=>  
```

### pwdx

プロセスで操作中のディレクトリを取得できる

### addr2line

xxx

### gstack

プロセスのスタックトレースをみる。

```
$ gstack pid
```

### csplit

正規表現によるファイル分割

```
$ cat test
###BB###
aaa
aa
###AA###
bb
b
b
b

$ csplit --suppress-matched test '/###.*###/' {*}
```

### join

2つのファイルのデータを共通のフィールド単位で結合

### awk 複数の記号をセパレータとして使用したい

```
#正規表現を使用するとできる
#以下はスペースと:と/を区切り文字として使用した場合の例

echo "2016/03/01 12:12:12" | awk -F'[ :/]' '{print $2}'
```

### ポートに紐づくPID

```bash
lsof -i :3000 |awk '{print $2}' |grep -v PID |xargs 
```

# git

よく使わない物もある

## X日前との差分

```bash
git diff HEAD 'HEAD@{6 month ago}'
```

## 空コミット

```bash
git commit --allow-empty -m “empty commit”
```

## 詳細ログ

export GIT_CURL_VERBOSE=1