突然シェル芸が勉強したくなったので、勉強したコマンドたちをまとめました。 シェル芸を忘れた未来の自分と、シェルは使ってるけどシェル芸のコマンドは知らない人向けです。 説明はできるだけ省いて、上から実行結果を見ていくだけで内容とシェル芸の雰囲気がつかめるよう努めました。
実施環境
紹介するコマンド
man
基本のキ。ホームポジションから手を離さず使い方を思い出せる。
$ man man
seq
連番を生成。1からなので注意。
$ seq 10 1 2 3 4 5 6 7 8 9 10
0から生成。
$ seq 0 5 0 1 2 3 4 5
bashの機能でも似たようなことができる。
$ echo {1..10} 1 2 3 4 5 6 7 8 9 10
shuf
出力の順番をシャッフルする。
$ seq 5 | shuf 3 4 2 1 5
tac
逆順に表示。
$ seq 5 | tac 5 4 3 2 1
rev
各行の文字列をリバースする。
$ echo "いろはにほへと" | rev とへほにはろい
yes
yを無限出力。
$ yes | head -5
y
y
y
y
y
文字を指定。
$ yes hello! | head -5
hello!
hello!
hello!
hello!
hello!
bc
文字列を計算する。
$ echo "1+2*3" | bc 7
tr
置換。引数に空白""指定不可。
$ echo 1 2 11 10 2 | tr " " "\n" 1 2 11 10 2 $ echo 1 2 11 10 2 | tr "12" "ab" a b aa a0 b
特定の文字列削除。
$ echo 1 2 11 10 2 | tr -d " " 1211102
cut
半角空白" "を区切り文字として3フィールド目を取得。区切り文字はデフォルトでタブ\t
$ echo 1 2 11 10 2 | cut -d" " -f3 11
-bでバイト目を取得。-cで文字目を取得だが、ubuntu@WSLではマルチバイト文字があるとエラーを吐いた。Macのcutは正しく動いた。
$ echo hello! | cut -b 2 e $ echo hello! | cut -b 2- ello!
sort
$ echo 1 2 11 10 2 | tr " " "\n" | sort 1 10 11 2 2 # --numeric-sort $ echo 1 2 11 10 2 | tr " " "\n" | sort -n 1 2 2 10 11 # --reverse $ echo 1 2 11 10 2 | tr " " "\n" | sort -nr 11 10 2 2 1 # --uniq $ echo 1 2 11 10 2 | tr " " "\n" | sort -nu 1 2 10 11
uniq
重複削除
$ echo 1 2 11 10 2 | tr " " "\n" | sort -n | uniq 1 2 10 11 # --duplicated $ echo 1 2 11 10 2 | tr " " "\n" | sort -n | uniq -d 2 # --count $ echo 1 2 11 10 2 | tr " " "\n" | sort -n | uniq -c 1 1 2 2 1 10 1 11
sed
置換。
# ABC -> XYZ sed 's/ABC/XYZ/g' # 10行目~20行目で置換 sed '10,20s/ABC/XYZ/g' # 2つ置換 sed -e 's/AAA/XXX/g' -e 's/BBB/YYY/g' # AAAを含む行のBBBをCCCへ置換 sed -e '/AAA/s/BBB/CCC/g'
行の削除。
# 1行目削除 sed 1d # 1~3行目削除 sed 1,3d # #から始まる行を削除 sed '/^#/d'
文字の削除。
sed -e "s/ABC//g"
awk
ある種のプログラミング言語なので詳細は他のサイトに譲る。基本はawk PATTERN{ACTION}
でif (PATTERN) ACTIONと捉えられる。
空白またはタブで区切られた5番目が10000以上のとき。
$ ls -l / | awk '$5 >= 10000 {print}' -rwxr-xr-x 1 root root 87944 Jan 1 1970 init $ ls -l / | awk '$5 >= 10000 {print $5}' 87944
ACTIONを省略すると{print}と同義。~は==の正規表現版。==はなぜか動かなかった。
$ ls -l / | awk '$6 ~ /Sep/' drwxr-xr-x 1 root root 512 Sep 13 22:07 dev dr-xr-xr-x 11 root root 0 Sep 13 22:07 proc drwxr-xr-x 1 root root 512 Sep 13 22:07 run dr-xr-xr-x 12 root root 0 Sep 13 22:07 sys drwxrwxrwt 1 root root 512 Sep 12 22:00 tmp
PATTERNを省略すると全行に適応
$ ls -l / | awk '{print $1,$2,$3}' | head -5 total 88 drwxr-xr-x 1 root drwxr-xr-x 1 root drwxr-xr-x 1 root drwxr-xr-x 1 root $ ls -l / | awk '{print $1$2$3}' | head -5 total88 drwxr-xr-x1root drwxr-xr-x1root drwxr-xr-x1root drwxr-xr-x1root
PATTERNには正規表現も可能
$ ls -l / | sed 1d | awk '/^[^d]/{print $9, "is not a directory"}' init is not a directory
NRはNum of Recordsで現在行が入るawkの変数。NFもある。
ls -l / | awk '/^[^d]/ && NR>1{print $9, "is not a directory"}' init is not a directory
--field-separator。区切り文字をデフォルトの"[ \t]+"から":"に変更。-F","でCSVに使える。
$ cat /etc/passwd | awk -F":" '$7 ~ /bash$/{print $1}' root dorapon
- ENDは最後に1回だけ実行されるPATTERN。BEGINもある。
- PATERN{ACTION}は並べて複数書ける。
- 仮想配列もある。ただし出力順番は不定。
- ACTION自身もセミコロン;で複数書ける。
- for,while,case,ifも雰囲気で使える。
$ ls -l / | awk 'NR>1{month[$6] += $5} END{print "The sum of capacity of each month."; for(m in month) print m,month[m],"bytes"}' The sum of capacity of each month. Sep 1536 bytes Jan 87944 bytes Apr 5120 bytes Jul 2560 bytes
xargs
空白タブ改行を一緒くたにまとめる。
$ echo "1 23\n4\t5 6 7\n\t89" 1 23 4 5 6 7 89 $ echo "1 23\n4\t5 6 7\n\t89" | xargs 1 23 4 5 6 7 89 # 2行ごと改行出力 $ echo "1 23\n4\t5 6 7\n\t89" | xargs -L2 1 23 4 5 6 7 89 # 1行ごと $ echo "1 23\n4\t5 6 7\n\t89" | xargs -L1 1 23 4 5 6 7 89 $ echo "1 23\n4\t5 6 7\n\t89" | xargs -L1 | tr " " "+" | bc 24 22 89
取得した複数のファイル名を1つづつ引数に取りたい時
$ grep -ils info /var/log/* /var/log/dpkg.log # xargsがないと出力自体を引数にとってしまう。 $ grep -ils info /var/log/* | tail -3 /var/log/dpkg.log $ grep -ils info /var/log/* | xargs tail -3 2018-09-06 22:47:28 trigproc man-db:amd64 2.8.3-2 <none> 2018-09-06 22:47:28 status half-configured man-db:amd64 2.8.3-2 2018-09-06 22:47:33 status installed man-db:amd64 2.8.3-2 # 実際に実行するコマンドは-tオプションで見られる。 $ grep -ils info /var/log/* | xargs -t tail -3 tail -3 /var/log/dpkg.log 2018-09-06 22:47:28 trigproc man-db:amd64 2.8.3-2 <none> 2018-09-06 22:47:28 status half-configured man-db:amd64 2.8.3-2 2018-09-06 22:47:33 status installed man-db:amd64 2.8.3-2
便利なオプション
grep
オプション | 説明 | 例 |
---|---|---|
-r, --recursive | 再帰的に探索 | grep Error -r /var/log |
-i, --ignore-case | 大文字小文字区別なし | grep Error -ri /var/log |
-l, --files-with-matches | ファイル名だけ出力 | grep Erro -rl /var/log |
-e, --regexp | 正規表現 | |
-o, --only-matching | 一致した文字を出力 | grep -e -o "eth[0-9]\+" hoge.log |
-v, --invert-match | を含まない | grep -v 0 dropstats.log |
-s, --nomessages | エラー出力なし |
ls
オプション | 説明 | 例 |
---|---|---|
-1 | 1行で表示 | ls -1 |
-t | 更新時間順 | ls -lt |
-S | サイズ順 | ls -lS |
-F | ディレクトリの後ろに/ | ls -lF |
乱数生成
bashの環境変数$RANDOMを使う場合。ただし、0~32767。
$ echo $((RANDOM%+101)) 47
連続で
$ yes 'echo $((RANDOM%+101))' | head -5 | bash 21 60 50 70 88
/dev/urandomを使う場合。
echo $(($(od -vAn -N1 -tu < /dev/urandom) % 101 )) 99