Here's a program I wrote to count matches in a very large file. I wonder how long it would take to work out the equivalent bash command.
use aho_corasick::AhoCorasick;
use std::fs::File;
use std::io::BufReader;
fn main() {
let args = std::env::args().collect::<Vec<_>>();
if args.len() != 3 {
eprintln!("Usage: ./count_occurances 'pattern' <filename>");
return;
}
let f = File::open(&args[2]).expect("Error opening input file");
let reader = BufReader::new(f);
let patterns = &[&args[1]];
let ac = AhoCorasick::new(patterns);
let count = ac.stream_find_iter(reader).count();
println!("{}", count);
}Half a second, unless I'm missing something?
No objections at all to people building simpler UIs for common tasks. The classic Unix tools are like table saws without labels or safety features - confusing and rightfully intimidating. You have to read the manual carefully to avoid chopping off digits.
... but they're also like table saws in that once you know them well and are comfortable with the usage patterns that protect you from the dangerous parts, they let you achieve things with a minimum of fuss and ceremony.
Yes.
$ echo aaaaaa | grep -c a
1grep -o $pattern $filename | wc -l
would work in that case, I think.
I did have to think for a minute to come up with that version. It was definitely still much faster for me than writing my own matching logic would have been, but that may well be different for other people.
$ echo aaaaaa | grep -c a
1On further Googling (about a minute this time, with a few different pages) I found that 'grep -o' would do the trick (and someone beat me to it, above.)
I'd still argue that one minute of Googling would be quicker than writing a program to do the same.
Plus it's written in a robust language. The `grep | wc` solution here looks ok, but in my experience bash hacks tend to be full of bugs, especially around quoting, whitespace, etc.
grep -o $pattern $filename | wc -l
But yours has better error handling!