既存ログを解凍して、
必要な箇所だけ取り出して新しくログを作るシェルスクリプトを扱った時の備忘録。
バージョン:GNU bash, version 3.2.25(1)-release
シバン
#!/bin/bash
数字の数え方
- シェルスクリプトでは先頭は1
引数を受け取る
sh shellfile.sh arg1 arg2 ... arg10
#「$数字」で番号の引数を取得
arg_1=$1
#二桁以上は{}で囲む
arg_10=${10}
出力結果をファイルへ書き出す
#file.txtにecho内容を上書き
echo hoge > file.txt
#file.txtを空にする
echo > file.txt
#file.txtに追記
echo hoge >> file.txt
クォートの使い分け
sh command arg1
#シングルクォート「''」は内容を文字列として出力する
echo '$1' #「$1」が出力される
#ダブルクォート「""」は変数を文字列として展開して出力する
echo "$1" #「arg1」が出力される
#バッククォート「``」はコマンドを実行した結果を出力する
fuga=`ls`
echo $fuga #lsの実行結果が文字列として出力される
変数やワイルドカードを使う
mv "$hoge"file* targetdir
sed -e 's#debug_'"$day"'/_##g'
標準出力(≒コンソールに出力される結果)の内容を別のコマンドに渡す
- パイプ"|"を利用する
解凍
#アーカイブの中身を確認する
tar -tf compressed.tgz
#「compressed.tgz」の中から「folder」配下のファイルを全て解凍する
tar xzvpf compressed.tgz folder/*
- x:解凍する
- z:gzip(.tgz、.tar.gz)を扱う
- v:処理ファイルを詳しく出力する
- p:権限を保つ
- f:ファイル名を指定する
パターンにマッチした文字列を抽出する
#先頭が「file」、末尾が「.txt」のファイルから'fuga'を含む行とその前2行を抽出
#さらにそこから「hoge」を含む行を抽出
grep -B 2 'fuga' file*.txt | grep 'hoge'
#検索条件に(){}|+?を使用したい場合はegrep
egrep 'hoge|huga' file.txt
- B 数字:指定数だけ前の行を表示
パターンにマッチした文字列の書換・削除
#マッチした値を全て置き換える
sed -e 's#置換前#置換後#g' file
- -e:基本正規表現を使用
- デミリタ(区切り文字):どの文字でもいい
行をソートする
sort -t "|" -k 5 sortfile.txt
- -t 文字:デミリタを指定(オプションなしの場合は半角空白が区切り文字)
- -k 数字:ソートに使用する列を指定
特定列で値を連結する
join -t \t -1 2 -2 3 -a 1 file1 file2
- -t 文字:デミリタを指定(オプションなしの場合は半角空白が区切り文字)
- -1 列番号:1つ目のファイルで一致に使う列を指定
- -2 列番号:2つ目のファイルで一致に使う列を指定
- -a ファイル番号:指定したファイルの全ての行を表示する。複数ファイルを全て表示したい場合は「-a 1 -a 2」のようにする
重複行の削除
uniq filename
デミリタで区切られたファイルの整形
#awk 'パターン {アクション}' 入力ファイル
awk -F "|" 'BEGIN{ OFS = "\t" } { sub(" ", "|", $0) } NF<11 { print "\""$1"\"", $10 } NF==11 { print $11, 'hoge' }'
- フィールド:1行の内、区切り文字で区切られた各データのこと。$1、$2という風に表す
- レコード:1行のこと
- $0:現在のレコードを表す
- -F:フィールド区切り文字を指定
- BEGIN{}:最初に一度だけ実行される処理を記述する
- OFS:出力時のフィールド区切り文字を示す組み込み変数
- NF:現在の入力レコードのフィールド数を示す組み込み変数
- 評価式:trueの場合のみ、{アクション}が実行される
- sub(置換対象文字列, 置換後文字列, 入力文字列):文字列置換
- """:awkでダブルクォーテーションを出力する場合は「"」でエスケープしたものを「""」で囲む
ファイルの行数を出力
wc filename
処理の状態を確認
top