🔖

zshのコマンド履歴みてみた

に公開

今回は、私の使っているzshに蓄えられた過去のコマンド履歴について、何を一番使ってきたのかをただ確認したかったので確認するためのコードを書いたという内容を共有します。

実装開始!!!

.zsh_historyのフォーマット

意外と~/.zsh_historyを直接みたことがある人は少ないのではないでしょうか?かくいう自分も今回はじめてみました。ファイルは以下のようになっています。以下は最初の20行をお見せしています。このようなフォーマットになっており、実行したコマンドは基本的には;の直ごに来ていそうなので、実装ではその部分を取り出すようにしました。

: 1702554011:0;python train.py --phase train --dataset_path /Users/<username>/work/datasets/mvtec_anomaly_detection --category carpet --project_root_path ./ --coreset_sampling_ratio 0.01 --n_neighbors 9
: 1702554011:0;vim hoge.py
: 1702554011:0;python hoge.py
: 1702554011:0;cp ../hoge/train .
: 1702554011:0;cp -r ../hoge/train .
: 1702554011:0;rg Start
: 1702554011:0;.config/nvim
: 1702554011:0;python hoge
: 1702554011:0;pip instalal scikit-learn
: 1702554011:0;ghq get git@github.com:hogehoge/hogehoge.git
: 1702554011:0;cd /Users/<username>/Desktop/git_default/github.com/hoge
: 1702554011:0;pyenv virtualenv 3.12-dev hoge-at
: 1702554011:0;pyenv virtualenv 3.10.9 hoge-at
: 1702554011:0;pyenv local 3.10.9/envs/hoge-at
: 1702554011:0;pip install numba
: 1702554011:0;vim utils/config.py
: 1702554011:0;python main.py -
: 1702554011:0;python main.py --help
: 1702554011:0;python main.py -pp /Users/<username>/work/datasets/mvtec_anomaly_detection
: 1702554011:0;pip uninstall faiss

プログラム

今回はPythonを使って~/.zsh_historyを読み込み、頻度順にCSV ファイルに保存するというものを作りました。

まずはコードをお見せします。今回作ったのは以下になります。

cmds = {}

with open("/Users/<username>/.zsh_history", "r", encoding="utf-8", errors="ignore") as f:
    for i, line in enumerate(f.readlines()):
        try:
            cmd = line.split(";")[1].split(" ")[0].strip()
        except:
            continue
        if cmd == "":
            continue

        if cmd in cmds:
            cmds[cmd] += 1
        else:
            cmds[cmd] = 1


with open("output.csv", "w") as f:
    f.write("cmd,num\n")
    for k, v in sorted(cmds.items(), key=lambda x: -x[1]):
        f.write(f"{k},{v}\n")

一つ目のwith構文で~/.zsh_historyを読み込んでいます。errors=ignoreにしている理由ですが、zsh_historyのファイルフォーマットの問題からか、単純に開こうとするとエラーが出てしまったので、エラーを無視する仕組みを入れました(ChatGPTありがとう)。

cmd = line.split(";")[1].split(" ")[0].strip()では履歴ファイルからコマンド部分だけを抽出しています。これはフォーマットでも紹介したように;の直後にコマンドが来ることが多かったためその部分を取り出す処理をしています。ちなみに例外がある場合としては、HOGE=10 python hoge.pyのように最初に環境変数を指定してから実行する場合は直後にコマンドが来ません。

cmdsという辞書にはコマンドごとに出現回数を保存しています。

最後に二つ目のwith構文では辞書の内容をCSVファイルにしています。sorted(cmds.items(), key=lambda x: -x[1])の部分では出現回数が多かった順番でソートさせる処理を書いています。

実行してみる

このコードを実行してみると以下のようなCSVファイルが取得できました。なおこの結果はTOP-50のコマンド等です

cmd,num
git,2212
vim,1081
rg,940
cd,492
rm,349
python,314
mkdir,301
ll,255
gcloud,251
docker,208
pip,191
uv,172
pyenv,156
sh,148
echo,137
less,131
mv,120
cp,113
docker-compose,106
brew,99
go,99
touch,98
tldr,81
cat,77
bat,76
isort,70
poetry,68
black,63
tree,43
ghq,40
pipenv,40
man,34
kubectl,28
mise,28
curl,27
npm,25
sudo,23
grep,22
gh,22
task,22
find,21
npx,21
terraform,21
ping,18
open,17
chmod,15
conda,15
export,15
which,15

結果をみると、gitを一番使っていました。ちゃんと開発をしてきたんだなということの証明にはなるのでほっとしています(gitが少なかったら落ち込んでましたw)。2番目がvimなのも納得です。普段cursorなども使いますが簡単な開発はvimでやっているのでこの回数でもびっくりしません。それ以外で言うと検索のためのrgやGoogle CloudのCLIgcloud、また比較的最近導入したuvも追い上げてきていますね。こうみるとcursorなどよりターミナルでの作業が多かったんだなと思い、何か感慨深いです。

なお、rguvコマンドについては過去に紹介記事を書いているので、読んでもらえると極めて喜びます!!!

https://zenn.dev/akasan/articles/25f1eca029854b

https://zenn.dev/akasan/articles/39f81f8bd15790

まとめ

今回は、私のパソコンの~/.zsh_historyを覗いてみました。ちゃんと開発してきた記録が残っていて嬉しいと思いつつ、例えば一年後全く同じことした時にこの順位がどう変わるのかとても気になりますね。皆さんもぜひ自分が普段どんなコマンドを使っているかみてみるのはいかがでしょうか?

Discussion