ビッグデータ分析で使用してきたシェルコマンドをまとめました。
ターミナル表示
echo で文字列エスケープ
$ echo "\""
"
echo で改行表示
- -e で改行を表示出来ます。
$ txt="a\nb\nc"
$ echo -e "$txt"
a
b
c
テキスト処理
文字列から offset を指定して抽出する
- 日付文字列から年月日を抽出する際に使用します。
$ d="20190630"
$ echo ${d:0:4}
2019
$ echo ${d:4:2}
06
文字列の長さを取得する
$ txt="abcdef"
$ echo ${#txt}
6
ファイル処理
tsvから特定の列を抽出する
- cut コマンドで取り出せます。
- ただし,複数列取り出せても順番を入れ替えることは出来ません。
$ cat test.tsv | cut -f3,4
- awk でも可能です。
- awk だと列を入れ替えることが出来ます。
- -F で区切り文字を指定します。
$ awk -F'\t' '{print $4 "\t" $3}' -f test.tsv
改行を除去する
$ cat test.txt | tr -d '\n'
行をシャッフルしてランダム出力する
- サンプリングで使います。
$ cat test.txt | shuf -n 5
先頭行を除いて表示する
- tsv でヘッダーを除いて表示する際に使います。
- awk で NR(Number of Record:行数)を使用します。
- tail -n +数字 で先頭から指定した行以降を表示します。
$ awk 'NR>1 {print}' test.tsv
$ tail -n +2 test.tsv
ファイル分割
- – は標準出力を指します。例では cat の出力を split で受け取っています。
- -l で分割したい行数を指定します。
- -d で分割した際のファイル名を数値とします。
- -a で分割ファイル名の桁数を指定します。
$ cat test.txt | split -l 100 -d -a 5 - tmp/
$ ls tmp
00000 00001 00002
複数ファイルを結合
- cat(concatenate)で結合出来ます。
- test1.txt の後ろに test2.txt を結合して test.txt として出力します。
cat test1.txt test2.txt > test.txt
ファイルを行単位で結合する
- -d , で行単位で複数ファイルを , 結合します。
- 複数ファイルから必要な値を抜き出して1個のファイルにする際に使用します。
$ paste -d , test1.txt test2.txt
文字コードを変換する
$ iconv -f sjis -t utf8
ファイル監視
- 実行ログを監視する際に使います。
$ tail -f target.txt
検索
grep でハイライト
$ grep '検索' test.txt --color=always
grep でヒットした行の行数を表示する
$ grep xxxxx test.txt -n
2588:xxxxx
grep でヒットした前後の行を表示
- -A n で後ろ n 行を表示します。
- -B n で前 n 行を表示します。
$ grep ‘word’ test.txt -A 2 -B 2
grep の検索対象文字列に変数を使用する
$ cond=`cat cond.txt`
$ grep -E ${cond} test.tsv
特定の列に条件を指定して検索する
- awk で実現可能です。
$ cat test.csv
1,test
2,テスト
3,text
4,テキスト
5,taste
6,テイスト
$ awk -F',' '$2~/test/' test.csv
3,test
- 変数を条件に指定することも可能です。
$ word="テスト"
$ awk -v word=${word} '$2 ~ word' test.csv
行数を取得する
- wc(word count)で行数を取得出来ます。
- データの件数を見る際によく使います。
$ cat test.txt | wc -l
重複を除いて行数を取得する
- ユニーク数を見る際によく使います。
$ cat test.txt | sort | uniq | wc -l
ls でフルパス表示する
- PWD(print working directory) を組み合わせます。
$ ls -ld ${PWD}/*
配列
文字列を特定の文字で区切って配列に格納する
- 複数のカラムのIDをアンダースコアで連結したものを分解する時に使います。
$ text="1_2_3"
$ arr=(`echo $text | tr -s '_' ' '`)
$ echo ${arr[0]}
1
$ echo ${arr[1]}
2
$ echo ${arr[2]}
3
配列の要素数を確認する
$ echo ${#array[@]}
日時処理
date で日時加減算
- 日時処理はよく使います。
# 2019-06-30 に1ヶ月加算し yyyy-mm 形式で出力する
$ date "+%Y-%m" -d "2019-06-30 1 month"
2019-07
# 2019-06-01 に1日加算し yyyy-mm-dd 形式で出力する
$ date "+%Y-%m-%d" -d "2019-06-01 - 1 day"
2019-05-31
計算処理
ターミナルで計算
- 電卓開くのが面倒かつターミナルで作業してる時にちょっとした計算をする際によく使います。
$ echo $((90*24*60*60))
7776000
データ量確認
ファイルのデータ量確認
- -b でバイト単位で表示します。
- -h で見やすい形式で表示します。
- -s で合計容量を表示します。
$ du . -b
1024 ./test1.txt
2048 ./test2.txt
$ du . -h
1M ./test1.txt
2M ./test2.txt
$ du . -s
3072 .
処理
- 重いシェルを流す時によく使います。
ログアウトしても処理を続ける
$ nohup heavy_process.sh &
バックグランドで処理を実行する
$ heavy_process.sh &
並列で処理する
- xargs で並列処理が可能です。
- ls で test ディレクトリのファイル一覧を表示して,並列数10で各ファイル名を引数に sample.sh を実行します。
- パフォーマンスチューニングでよく使います。
$ ls test | xargs -L 1 -P 10 bash -c './sample.sh $0'
処理時間計測
- SECONDS を使うパターンと date コマンドの差分を取るパターンがあります。
- シェルスクリプトでログに処理時間を出力したい時などに使います。
$ SECONDS=0
$ test.sh
$ echo $SECONDS
$ start_time=$(date +%s)
$ test.sh
$ end_time=$(date +%s)
$ echo $((${end_time}-${start_time}))
その他
コマンドの出力を変数に格納する
$ dict=$(cat dict.txt)
$ echo $dict
$ dict=`cat dict.txt`
$ echo $dict
-(ハイフン)で標準入出力をコマンド引数で扱う
- – で標準入出力をコマンド引数で扱うことが出来ます。
- wget -O ファイル名 を wget -O – でダウンロードしたファイルを標準出力として扱います。
- apt-key add ファイル名 を apt-key add – で標準入力をaptの公開鍵として登録します。
$ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
標準出力・標準エラー出力のリダイレクト
- > または 1> で標準出力をリダイレクトします。
- 2> で標準エラー出力をリダイレクトします。
- &> で標準出力・標準エラー出力をリダイレクトします。
- > で標準出力をファイルに上書きします。
- >> で標準出力をファイルに上書きします。
- ログ出力や標準出力をファイルに書き出すとき等に使用します。
# 標準出力をファイルにリダイレクトする
$ test.sh > result.log
$ test.sh 1> result.log
# 標準エラー出力をファイルにリダイレクトする
$ test.sh 2> error.log
# 標準出力・標準エラー出力を1ファイルにリダイレクトする
$ test.sh &> result.log
# 標準出力・標準エラー出力を別ファイルにリダイレクトする
$ test.sh 1> result.log 2> error.log
# 標準出力をファイルに上書きする
$ test.sh > result.log
# 標準出力をファイルに追記する
$ test.sh >> result.log
for 文
max=10
for ((i=0; i < $max; i++)); do
echo $i
done
ログ出力関数
function write_log(){
# Usage:
# $ write_log "/tmp/test.log" "this is test."
# Description:
# 指定したファイルにログを出力します。
# Arguments:
# $1: ログファイル
# $2: ログ出力メッセージ
#
echo "$(date '+%Y-%m-%d %H:%M:%S'): $2" >> $1
return 0
}