質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

Q&A

解決済

1回答

1448閲覧

シェルスクリプトで月末月初のログファイルを分けて取得する方法を教えていただけますでしょうか。

wakahiro

総合スコア20

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

0グッド

3クリップ

投稿2020/09/15 09:33

毎週月曜日に1度、直近1週間分のアクセスログを取得し、その中からクライアントIPを抽出するという作業を行なっています。
こちらの処理で月末・月初に限り、一週間区切りではなく、その1週間のうち月末分と月初分で分けて集計を行いたいのですがどのようにシェルスクリプト内に処理の記述すればよいかわからずみなさまにお力をお借りしたく今回質問させていただきました。

例えば2020年9月7日集計日の場合
1、2020年8月31日
2、2020年9月1日-9月6日
と上記のように先月末と残り月初で期間を2つに分けて処理を行なうイメージです。

流れとしましては以下①②コマンドを使用し
-accessログが置いてあるディレクトリ内から対象期間のログをリスト化(logfile_list.txt-date '+%Y%m%d')
-その後リストに書かれているファイルのパスを一行ずつ指定してファイルの内容をcatコマンドとawkコマンドで抽出
上記で抽出されたものをIPリスト(output.iplist.txt-date '+%Y%m%d' )としています。

①、対象期間のログをリストファイル化

for i in `seq 1 7` ;do  ls  /var/log/nginx_log/*access*`date '+%Y%m%d' --date "$i day ago "` >> /var/tmp/logfile_list.txt-`date '+%Y%m%d'` ;done ※ログファイル名フォーマット access.log-yyyymmdd ssl=access.log-yyyymmdd

②、①で取得したリストでファイルの内容を出力しIPの個所のみ抽出(重複分は削除)

for i in $(cat /var/tmp/logfile_list.txt-`date '+%Y%m%d'`) ;do awk -F',' '{print $2}' $i | tr -d ' client: '| sort | uniq >> /var/tmp/output.iplist.txt-`date '+%Y%m%d'` ;done

こちらを記載したシェルスクリプトをcronで毎週月曜日に実行されるように設定しています。
月末月初以外だと月が変わらず1週間分のIPを取得できるのですが、上記の処理内容だと仮に2020年9月7日に集計のスクリプトが実行された場合抽出されたIPリストに2020年9月1日-9月6日と2020年8月31日分が混ざったアクセスIPが出力される形になります。
自動で毎週集計されるという仕組みは変えずに、ファイルの中身に処理を追記して月末・月初は先月末分と月初分で処理を分けてくれる処理の書き方をご存じの方はお力をお貸しいただけると大変助かります。
出力されるファイルが複数になってしまっても構いません。

文章が読みづらく申し訳ないのですがよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hidezzz

2020/09/15 10:16 編集

スクリプトだけだと仕様を解析するのがつらいです。 差し支えのある部分は加工したり隠したりしても良いので、問題再現するレベルのログファイルと、現在結果がどのようになって、それがどのようになれば良いのかの具体例を提示してもらえますか?
mit0223

2020/09/15 10:41

要求仕様の確認です。 ・1行で書かなければならないという制限があるのでしょうか? ・中間ファイル /var/tmp/logfile_list.txt-YYMMDD も生成する必要があるのでしょうか?
hana_yama_san

2020/09/15 11:51 編集

あのですね、質問を拝見すると、何となくロジックとかは判るのですよ。 dateで日にちを取得して%dが6以下なら月をまたいでいるだろう、とか その%dと7との差分が前月分だとか・・しかも提示いただいている 2個のスクリプトは纏められるんじゃないかな〜とか・・ でも実際検証するとなると工数が大変なのですよ、 せめてテストデータを月またぎ・ぎりぎり一日始まり・月の中日の 合計21日分用意して欲しいですね。
guest

回答1

0

ベストアンサー

当月と前月で2回に分けるんですよね?改善点はさておいて、grepで。

bash

1for i in $(grep -v `date +log-%Y%m` /var/tmp/logfile_list.txt-`date +%Y%m%d`) 2do awk -F',' '{print $2}' $i | tr -d ' client:'| sort | uniq >> /var/tmp/output.iplist.txt-`date +%Y%m%d`ZENGETSU 3done 4 5for i in $(grep `date +log-%Y%m` /var/tmp/logfile_list.txt-`date +%Y%m%d`) 6do awk -F',' '{print $2}' $i | tr -d ' client:'| sort | uniq >> /var/tmp/output.iplist.txt-`date +%Y%m%d`TOUGETSU 7done

投稿2020/09/15 12:07

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hana_yama_san

2020/09/15 12:35

コロンブスの卵といえば言い過ぎかもしれませんが、 grep -v は実にロジックをシンプルにしています。 あとは、個々の運用方針次第でしょうね。 7日から月末まで空処理が走るのを許容するかどうか。 ・・しかしスクリプトは見事です。
otn

2020/09/15 12:38

> 出力されるファイルが複数になってしまっても構いません。 ということなので、手を抜ける部分は手を抜いてます。
otn

2020/09/15 12:42 編集

そもそも論としては、週次の処理と月次の処理を全く独立して動かすのが良い気もします。 ・週初に、月を無視した週ごとのファイル ・月初に、週を無視した月ごとのファイル の両方を作る。サイズが倍になるので、ディスクをケチるなら駄目ですが。
wakahiro

2021/01/27 15:08

返事が遅くなり申し訳ありません。 こちらで問題が解決できました。 大変助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問