uniq.ha (1265B)
1 use sort; 2 use sort::cmp; 3 use fmt; 4 use io; 5 use os; 6 use strings; 7 use bufio; 8 use encoding::utf8; 9 use getopt; 10 11 use util; 12 13 let delim = "\n"; 14 let newline = true; 15 16 fn run() void = { 17 let sc = bufio::newscanner(os::stdin); 18 defer bufio::finish(&sc); 19 20 let lines: []str = []; 21 defer free(lines); 22 23 for (true) { 24 match (bufio::scan_line(&sc)) { 25 case let s: str => append(lines, strings::dup(s)!)!; 26 case io::EOF => break; 27 case let e: utf8::invalid => util::die(utf8::strerror(e)); 28 case let e: io::error => util::die(io::strerror(e)); 29 }; 30 }; 31 32 sort::sort(lines, size(str), &cmp::strs)!; 33 34 let prev = ""; 35 for (let i = 0z; i < len(lines); i += 1) { 36 if (lines[i] == prev) continue 37 else fmt::printf("{}{}", lines[i], if (i != len(lines) - 1) delim else "")!; 38 prev = lines[i]; 39 }; 40 }; 41 42 export fn main() void = { 43 let cmd = getopt::parse(os::args, 44 "unique", 45 ('d', "delim", "set a deliminer between printed tokens"), 46 ('n', "print a newline on exit (default)"), 47 ('N', "don't print a newline on exit") 48 ); 49 defer getopt::finish(&cmd); 50 51 for (let opt .. cmd.opts) { 52 switch (opt.0) { 53 case 'd' => delim = util::escape(opt.1); 54 case 'n' => newline = true; 55 case 'N' => newline = false; 56 case => abort(); 57 }; 58 }; 59 60 run(); 61 62 if (newline) fmt::println()!; 63 };