shell historyをtimestampでフィルターする

awk command 3/N

公開日: 2022-08-10
更新日: 2024-04-09

  Table of Contents

今回作成したシェルスクリプト

仕様

  • STARTENDの2つのtimestampを指定
  • ~/.zsh.d/.zsh_historyに格納されたzsh historyから, STARTENDの範囲内(境界含む)の履歴を抽出し, 標準出力
  • コマンドの実行時刻はhuman readableな形へ変換する


今回作成したシェルスクリプトは以下です. なおファイルパーミッションは 700 で指定しています.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
## grep the history file with search words
## Author: Ryo Nakagami
## Revised: 2024-04-09
## REQUIREMENT: gawk

set -e

# Variable
HISTORYFILE=~/.zsh.d/.zsh_history
START_UNIX_TIME=$(date +%s --date $1)
END_UNIX_TIME=$(date +%s --date $2)

# Main
cat $HISTORYFILE |
    awk -v start=$START_UNIX_TIME -v end=$END_UNIX_TIME -F":" \
        '($2 >= start) && ($2 <= end)\
        {$2=strftime("%Y-%m-%d %H:%M:%S", $2)";"; print $0}'

前提条件 !

~/.zsh.d/.zsh_historyに格納されたzsh historyにはunixtimeで実行時刻が格納されていますが, デフォルトの設定では格納されていません.

unixtime付きで履歴を格納する場合には .zshrcに以下の設定を書き加えます

1
setopt extended_history

コマンド解説

日付 から unixtime への変換方法

~/.zsh.d/.zsh_historyには以下のようにunixtime形式で実行時刻が格納されています

1
2
3
4
5
6
% cat ~/.zsh.d/.zsh_history | head -5
: 1690174802:0;history
: 1690174804:0;ls
: 1690174807:0;ls -a
: 1690174823:0;ls -l
: 1690174824:0;ls

そのため, timestampでfilterを実施する際にはunixtimeへの変換が必要になります.

date command

  • date コマンドに +%s 引数をつけると unixtime で表示
  • 特定の日付を変換したいときは、–date オプションを利用
1
2
3
4
5
6
7
8
9
10
# 現在時刻のunixtime
% date +%s
1712646571

# 特定の日付変換
% date +%s --date 2021-01-01
1609426800

% date +%s --date '2021-01-01 00:01:00'
1609426860

awk commandでのfilter

awk syntax

1
% awk 'pattern { action }'
  • パターンは入力レコードをベースに指定されたregex や expressionを用いてマッチ判定を行う
  • アクションの目的はawkに対してパターンがマッチしたときに何を行うかを示す

今回は, :でseperateされた列の2列目がunixtimeにあたるので$2を対象に入力されたtimestampとの比較を行絵ば良いことになります.

1
2
3
4
cat $HISTORYFILE |
    awk -v start=$START_UNIX_TIME -v end=$END_UNIX_TIME -F":" \
        '($2 >= start) && ($2 <= end)\
        {$2=strftime("%Y-%m-%d %H:%M:%S", $2)";"; print $0}'

パターンの指定は ($2 >= start) && ($2 <= end) が該当箇所となります. start, endawk コマンド実行時に定義した変数となります.

変数定義: awk -v var=value

awkのプログラムに, 変数を渡すにあたって

1
% awk -v var=value

を用いています. 複数渡したい場合は, 上記の例のように

1
% awk -v start=$START_UNIX_TIME -v end=$END_UNIX_TIME 

unixtime カラムのtimestamp型への変換

awkでもアクションにて以下の前半でunixtime カラムのtimestamp型への変換を実施しています

1
{$2=strftime("%Y-%m-%d %H:%M:%S", $2)";"; print $0}

strftime()関数はフォーマットとUnix時間を引数として変換する関数です. その実行結果を $2 という形で2カラム目に代入しています.

Appendix: 直近のzsh履歴をtimestamp付きで表示する場合

history -iコマンドで以下のように実行時間と一緒に履歴を確認することができます

1
2
3
4
5
6
% history -i -5
23129  2024-04-09 17:43  ls -lh
23130  2024-04-09 17:43  cd
23131  2024-04-09 17:43  ls -a
23132  2024-04-09 17:58  cd
23133  2024-04-09 18:00  history -i

一行目は行数をあらわしており, history [開始行] [終了行]で範囲を指定して表示することもできます

1
2
3
% history -i 23133 23134
23133  2024-04-09 18:00  history -i
23134  2024-04-09 18:00  history -i -5

References



Share Buttons
Share on:

Feature Tags
Leave a Comment
(注意:GitHub Accountが必要となります)