-
-
Save agentultra/7238694f3669826c4015 to your computer and use it in GitHub Desktop.
agealyzer: given a root directory, spits out histogram of ages of files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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)))))))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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