Skip to content

Instantly share code, notes, and snippets.

@agentultra
Forked from clee/agealyzer.clj
Last active February 25, 2016 20:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agentultra/7238694f3669826c4015 to your computer and use it in GitHub Desktop.
Save agentultra/7238694f3669826c4015 to your computer and use it in GitHub Desktop.
agealyzer: given a root directory, spits out histogram of ages of files
(ns clee.agealyzer)
(require '[clojure.java.io :as io])
(defn date [x] (java.util.Date. x))
(defn is-file? [f] (.isFile f))
(defn last-modified [f] (.lastModified f))
(defn get-year [x] (.getYear x))
(defn process-dir
([dir]
(let [files (filter is-file? (file-seq (io/file dir)))]
(map (fn [x] (+ 1900 (get-year (date (last-modified x))))) files))))
(defn get-date-map
[_map, _dates]
(loop [m _map
d _dates]
(if d
(recur (let [b (first d)] (assoc m b (+ 1 (get m b 0)))) (next d))
m)))
(defn -main
"Given a directory, spits out a histogram of file ages"
([] (println "usage: agealyzer <path/to/dir>"))
([path]
(let [m (into (sorted-map) (get-date-map {} (process-dir path)))
maxValue (apply max (vals m))]
(doseq [entry m]
(let [p (* 40.0 (/ (val entry) maxValue))
pf (apply str (repeat (int p) "="))]
(println (format "%4d: |%-40s| (%d)" (key entry) pf (val entry))))))))
package main
import (
"flag"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
)
func main() {
flag.Parse()
root := flag.Arg(0)
years := make(map[int]int)
filepath.Walk(root, func(path string, f os.FileInfo, err error) error {
if !f.Mode().IsRegular() {
return nil
}
year := f.ModTime().Year()
years[year]++
return nil
})
maxHits := 0
keys := []int{}
for year, hits := range years {
keys = append(keys, year)
if hits > maxHits {
maxHits = hits
}
}
sort.Ints(keys)
bar := strings.Repeat("=", 40)
for _, k := range keys {
hits := years[k]
p := int(40.0 * hits / maxHits)
fmt.Printf("%d: |%-40.*s| (%d)\n", k, p, bar, hits)
}
}
#!/usr/bin/env python
from __future__ import print_function
from sys import argv
from collections import defaultdict
from os import walk, stat
from os.path import join, isfile, islink
from time import gmtime
years = defaultdict(int)
for root, dirs, files in walk(argv[1]):
for name in files:
filename = join(root, name)
if not isfile(filename) or islink(filename):
continue
year = gmtime(stat(filename).st_mtime).tm_year
years[year] += 1
maxHits = max([years[year] for year in years])
for year in sorted(years.keys()):
hits = years[year]
print('%d: |%%-40.%ds| (%d)' % \
(year, (40.0 * hits / maxHits), hits) % ('=' * 40))
#!/usr/bin/env ruby
# ported the script to ruby (kinda) for comparison purposes
require 'find'
if ARGV.length != 1 or not File.directory? ARGV[0]
puts "usage: agealyzer.rb </path/to/dir>"
exit 1
end
years = {}
Find.find(ARGV[0]) do |f|
if not File.file? f then next end
year = File.stat(f).mtime.year
if years[year]
years[year] += 1
else
years[year] = 1
end
end
maxHits = 0
years.each_key do |year|
if maxHits < years[year]
maxHits = years[year]
end
end
years.keys.sort.each do |year|
hits = years[year]
bars = ('=' * ((40.0 * hits) / maxHits)).ljust(40)
print "#{year}: |#{bars}| (#{hits})\n"
end
extern crate libc;
extern crate time;
extern crate walkdir;
use walkdir::WalkDir;
use std::path::Path;
use std::env;
use std::collections::BTreeMap;
use std::os::unix::fs::MetadataExt;
use std::iter::repeat;
use time::*;
fn main() {
let args: Vec<String> = env::args().collect();
let mut years: BTreeMap<i32, u64> = BTreeMap::new();
let directory;
match args.len() {
2 => {
directory = Path::new(&args[1]);
},
_ => {
panic!("usage: agealyzer </path/to/directory>");
}
}
for entry in WalkDir::new(&directory) {
match entry {
Ok(dir) => {
let meta = dir.path().metadata().unwrap();
if !meta.is_file() {
continue;
}
let mtime = meta.mtime();
let mtime_nsec = meta.mtime_nsec();
let utc = at_utc(Timespec::new(mtime, mtime_nsec as i32));
let year = 1900 + utc.tm_year;
*years.entry(year).or_insert(0) += 1;
},
Err(e) => println!("Shit! {:?}", e),
}
}
let zero = 0u64;
let max_hits = match years.values().max() {
Some(m) => m,
None => &zero,
};
for y in years.keys() {
let hits = match years.get(&y) {
Some(h) => h,
None => &zero,
};
let p = (40.0 * *hits as f64) / *max_hits as f64;
let pf = repeat("=").take(p as usize).collect::<String>();
println!("{0}: |{1: <40}| ({2})", y, pf, hits);
}
}
import asyncio
import os
import sys
import time
from collections import defaultdict
from functools import partial
async def walkdir(path, callback=None):
for entry in os.scandir(path):
if entry.is_dir(): await walkdir(entry.path, callback=callback)
if callback is None:
print(entry.name)
else:
callback(entry)
def count_file_year(file_year_histogram, entry):
stat_info = entry.stat(follow_symlinks=False)
year = time.gmtime(stat_info.st_mtime).tm_year
file_year_histogram[year] += 1
def print_histogram(file_year_histogram):
maxHits = max(file_year_histogram.values())
for year in sorted(file_year_histogram.keys()):
hits = file_year_histogram[year]
print('%d: |%%-40.%ds| (%d)' % (
year, (40.0 * hits / maxHits), hits) % ('=' * 40))
if __name__ == '__main__':
file_year_histogram = defaultdict(int)
count = partial(count_file_year, file_year_histogram)
loop = asyncio.get_event_loop()
loop.run_until_complete(walkdir(sys.argv[1], callback=count))
print_histogram(file_year_histogram)
2000: | | (2)
2003: | | (3)
2004: | | (152)
2005: | | (834)
2006: |= | (1866)
2007: |= | (2416)
2008: |== | (3834)
2009: |========================= | (33788)
2010: |=========== | (14994)
2011: |========================================| (53354)
2012: | | (1)
2013: | | (89)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment