はじめに
CYBIRD Advent Calendar 2022 の14日目担当の@cy-naullと申します。2021年新卒入社、2年目のサーバサイドエンジニアです。
13日目は、@dave_cさんの「Laravel Actionsのご紹介」で、日本語にわかりやすく翻訳されており、内容もとても興味深いものでした!
概要
業務などで、「これ手作業でできるけど、めんどくさくない...?」という経験があるのではないかと思います。1回くらいなら手作業で済ませた方が早いこともありますが、定常的に発生するものですと、手間もかかりミスも起こり得ることもあります...。
今回はそういった作業を、sedなどを使用したシェルスクリプトで手間を減らそう!という記事となっております。なお、今回の作業環境はmacOSとなります。
目次
1. 手作業で行っていたものについて
2. シェルスクリプトで実行できるようにする
3. まとめ
1. 手作業で行っていたものについて
簡易的にまとめると、月の初めに2つのサーバにある先月のログを1つにまとめ、特定のワードについて取り出し、データを整形する、といった作業になります。これらの作業を以下に分割し、シェルスクリプトで実行できるようにしていこうと思います。
- 2つのサーバにある先月のログを1つにまとめる
- 特定のワードについて取り出す
- データを整形する
2. シェルスクリプトで実行できるようにする
2つのサーバにある先月のログを1つにまとめる
まずは、サーバ上にある複数のログをローカルにSCPで持ってきて、1つにまとめます。今回、2つのサーバにあるファイル名が同じなので上書き防止のためSCPした後にリネームを行っています。
一括で複数ファイルをリネームする方法は以下のサイトを参考にさせていただいております。
#!/bin/zsh
# 先月のログのみ取得したいので、フォーマットを整え変数化する
LASTMONTH=`date -v -1m +'%Y%m'`
# ローカル上に新規フォルダを作成、移動
mkdir ~/hoge/${LASTMONTH}
cd ~/hoge/${LASTMONTH}
# scpマンドで先月のフォルダを指定し、対象のファイルを先ほど作成したフォルダに格納
scp -i key user@***.***.***.**1:~/logs/${LASTMONTH}/server.log.\*.gz ~/hoge/${LASTMONTH}/
# 取得したファイル群に、1つ目のサーバからのものと分かるようmvでリネーム
# ※sedで、"/"を使用すると階層を表す「/」と混ざりうまくいかないので今回は"|"を使用
ls *.gz | sed -e 's|.gz||g' | xargs -IX mv X.gz X_web1.gz
# 2つ目のサーバからも同様に取得
scp -i key user@***.***.***.**2:~/logs/${LASTMONTH}/server.log.\*.gz ~/hoge/${LASTMONTH}/
# grep -v で1つ目のサーバから取得したものを除外し、リネームする
ls *.gz | grep -v _web1 | sed -e 's|.gz||g' | xargs -IX mv X.gz X_web2.gz
実行後①
対象のファイルが取得でき、それぞれのファイル名の末尾に、どのサーバから取得したものかの情報がリネームにより追加されています。
$ cd ~/hoge/202211
$ ls
server.log.20221101_web1.gz
server.log.20221101_web2.gz
server.log.20221102_web1.gz
server.log.20221102_web2.gz
...
特定のワードについて取り出す
続いて、取得したログについて特定のワードで抽出し、テキストファイルに書き込んでいきます。
# ">>"を使用することで、追記書き込みになる
zgrep 'hoge' ~/hoge/${LASTMONTH}/server.log.${LASTMONTH}* >> ~/hoge/${LASTMONTH}/${LASTMONTH}.txt
zgrep 'fuga' ~/hoge/${LASTMONTH}/server.log.${LASTMONTH}* >> ~/hoge/${LASTMONTH}/${LASTMONTH}.txt
(取得したいワード分繰り返す)
実行後②
ログの中にある特定のワードについて、行単位で取得できています。
$ less 202211.txt
~/hoge/202211/server.log.20221101_web1.gz:1667228400,"hoge","aaa","111" ...
~/hoge/202211/server.log.20221101_web2.gz:1667228400,"hoge","bbb","222" ...
~/hoge/202211/server.log.20221102_web1.gz:1667314800,"fuga","ccc","333" ...
~/hoge/202211/server.log.20221102_web2.gz:1667314800,"fuga","ddd","444" ...
...
データを整形する
最後に、抽出したデータを整形していきます。今回整えたい内容としては、下記となります。
- データの中に不要なテキスト(抽出したフォルダ名)があるためそれらを削除
- データにUNIXTIMEがあり、これらをシステム標準時に変換
# ログに抽出したフォルダ名が記載されているため、sedで削除
sed -i -e 's|.*gz:||g' ~/hoge/${LASTMONTH}/${LASTMONTH}.txt
# UNIXTIMEをcutで決め打ちで取得
export UNIXTIME=`eval cut -b 1-10 ${LASTMONTH}.txt`
# for文で1つずつ、dateでフォーマットした日付に変換し、sedで置換する
for time in ${UNIXTIME[@]}; do
export NEWTIME=`eval echo "$(date -r $time +'%Y/%m/%d %H:%M:%S')"`
sed -i -e "s|$time|$NEWTIME|g" ./${LASTMONTH}.txt
done
実行後③
整形前にあった不要なテキストが削除され、UNIXTIMEも標準時間に変換されています。
$ less 202211.txt
2022/11/01 00:00:00,"hoge","aaa","111" ...
2022/11/01 00:00:00,"hoge","bbb","222" ...
2022/11/02 00:00:00,"fuga","ccc","333" ...
2022/11/02 00:00:00,"fuga","ddd","444" ...
...
3. まとめ
今回シェルスクリプトを作成してみて、便利なコマンドが沢山あるのだと勉強になりました!
手作業でできるけど、コード書くのも大変かなと思っておりましたが、毎月手作業で行っていたものがなくなりハッピーです。
次回、CYBIRD Advent Calendar 2022 の15日目は、@kanachaさんの「unity1week「そろえる」の参加記録」です。お楽しみに!