#!/usr/bin/perl use Getopt::Std; sub HELP_MESSAGE { print "uuniq [-c | -d | -u] [-i] [-l] [-f num] [-s chars] [file...]\n"; print "\treport or filter out repeated lines in an unsorted file\n"; print "-c: print the number of matching lines before each line\n"; print "-d: only output lines that are repeated\n"; print "-f num: ignore the first num fields\n"; print "-i: case insensitive\n"; print "-l: print the last line matched (rather than the first)\n"; print "-s chars: ignore the first chars characters\n"; print "-u: only output lines that are not repeated\n"; exit 1; } sub VERSION_MESSAGE { print "chri's uuniq, version 1.0\n"; } sub match_what { local $_ = shift; $_ = lc if $opt_i; for(my $i = 0; $i < $opt_f; $i++) { $_ =~ s/^\s*[^\s]+//; } $_ = substr $_,$opt_s; return $_; } getopts('clduif:s:'); my $wait_til_end = $opt_c || $opt_l || $opt_d || $opt_u; my %line_count, %line_where, @output_lines; $output_lines[0] = '' if $opt_l; while(<>) { my $match = match_what($_); if(!$wait_til_end) { print unless $line_count{$match}; } else { if($opt_l) { $output_lines[$line_where{$match}] = ''; $output_lines[$#output_lines+1] = $_; $line_where{$match} = $#output_lines; } else { $output_lines[$#output_lines+1] = $_ unless $line_count{$match}; } } $line_count{$match}++; } if($wait_til_end) { for $_ (@output_lines) { next unless $_; my $match = match_what($_); next if $opt_d && $line_count{$match} < 2; next if $opt_u && $line_count{$match} >= 2; if($opt_c) { printf('%4d %s', $line_count{$match}, $_); } else { print; } } }