Skip to content

Instantly share code, notes, and snippets.

@BjoernSchilberg
Forked from kokoscript/zsh-stats.py
Created February 26, 2022 20:08
Show Gist options
  • Save BjoernSchilberg/eaad9cd97d1a9126409663403ecd3ca7 to your computer and use it in GitHub Desktop.
Save BjoernSchilberg/eaad9cd97d1a9126409663403ecd3ca7 to your computer and use it in GitHub Desktop.
Stats from .zsh_history
import time
import re
hist = []
commands = []
count = 0
trueCount = 0
# by year
yearCounts = {}
monthCounts = {}
weekCounts = {}
dayCounts = {}
# total over all years
weekdayCounts = {}
hourCounts = {}
commandCounts = {}
longestCommand = ""
with open('.zsh_history', 'r', encoding="ISO-8859-1") as histFile:
hist = histFile.readlines()
histFile.close()
print("Analyzing...")
for line in hist:
count += 1
if line.find(": ") == 0:
trueCount += 1
epochTime = line[2:12]
command = line[15:(len(line) - 1)]
commands.append({
"time": epochTime,
"command": command
})
# time stats
timeStruct = time.localtime(int(epochTime))
year = time.strftime("%Y", timeStruct)
month = time.strftime("%b %Y", timeStruct)
week = time.strftime("%W-%Y", timeStruct)
day = time.strftime("%Y-%m-%d", timeStruct)
weekday = time.strftime("%a", timeStruct)
hour = time.strftime("%H", timeStruct)
if year not in yearCounts:
newDict = {year: 0}
yearCounts.update(newDict)
yearCounts[year] += 1
if month not in monthCounts:
newDict = {month: 0}
monthCounts.update(newDict)
monthCounts[month] += 1
if week not in weekCounts:
newDict = {week: 0}
weekCounts.update(newDict)
weekCounts[week] += 1
if day not in dayCounts:
newDict = {day: 0}
dayCounts.update(newDict)
dayCounts[day] += 1
if weekday not in weekdayCounts:
newDict = {weekday: 0}
weekdayCounts.update(newDict)
weekdayCounts[weekday] += 1
if hour not in hourCounts:
newDict = {hour: 0}
hourCounts.update(newDict)
hourCounts[hour] += 1
# command stats
if len(command) > len(longestCommand):
longestCommand = command
# match with "(^[A-Za-z0-9./_\-+]+)|((?<=sudo )[A-Za-z0-9./_\-+]+)|((?<=\| )[A-Za-z0-9./_\-+]+)|((?<=&& )[A-Za-z0-9./_\-+]+)"gm
# - command at the beginning of a line
# - command after a '|'
# - command after a '&&'
# - after sudo (and including sudo)
# it's not perfect, and misses a few commands + gets false positives
# findall doesn't really work in a friendly way, so do all groups seperately
commandsInLine = re.findall("(^[A-Za-z0-9./_\-+]+)", command)
for comm in commandsInLine:
if comm not in commandCounts and comm != '':
newDict = {comm: 1}
commandCounts.update(newDict)
elif comm != '':
commandCounts[comm] += 1
commandsInLine = re.findall("((?<=sudo )[A-Za-z0-9./_\-+]+)", command)
for comm in commandsInLine:
if comm not in commandCounts and comm != '':
newDict = {comm: 1}
commandCounts.update(newDict)
elif comm != '':
commandCounts[comm] += 1
commandsInLine = re.findall("((?<=\| )[A-Za-z0-9./_\-+]+)", command)
for comm in commandsInLine:
if comm not in commandCounts and comm != '':
newDict = {comm: 1}
commandCounts.update(newDict)
elif comm != '':
commandCounts[comm] += 1
commandsInLine = re.findall("((?<=&& )[A-Za-z0-9./_\-+]+)", command)
for comm in commandsInLine:
if comm not in commandCounts and comm != '':
newDict = {comm: 1}
commandCounts.update(newDict)
elif comm != '':
commandCounts[comm] += 1
print(f"Total commands: {trueCount}")
print(f"Longest command: {longestCommand}")
print("\nBy year:")
for year in yearCounts:
print(f"\t{year}\t{yearCounts[year]}")
print("\nBy month:")
for month in monthCounts:
print(f"\t{month}\t{monthCounts[month]}")
print("\nBy week:")
for week in weekCounts:
print(f"\t{week}\t{weekCounts[week]}")
print("\nBy day:")
for day in dayCounts:
print(f"\t{day}\t{dayCounts[day]}")
print("\nBy weekday:")
for weekday in weekdayCounts:
print(f"\t{weekday}\t{weekdayCounts[weekday]}")
print("\nBy hour:")
for hour in hourCounts:
print(f"\t{hour}:00\t{hourCounts[hour]}")
print("\nCommand stats:")
for comm in commandCounts:
print(f"\t{comm}\t{commandCounts[comm]}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment