frequency.nct
use std/cli.Application
use std/io.{BlockingFile, BlockingReader}
use std/io
use std/path.Utf8Path
use std/string.String
see ./index.nct
blocking func run(): i32! {
var application = Application.new("line-frequency", "Count matching lines in one file.")?
application.add_positional("PATH", true, "UTF-8 file to read.")?
application.add_positional("NEEDLE", true, "Exact line to count.")?
let arguments = application.parse_process() catch failure {
if !failure.has_code("std.cli.missing_positional")
&& !failure.has_code("std.cli.unexpected_positional") {
return move failure
}
let usage = application.usage()
io.print(&usage)?
io.print("\n")?
return 2
}
let requested = arguments.positional("PATH") otherwise { return 2 }
let requested_needle = arguments.positional("NEEDLE") otherwise { return 2 }
let path = Utf8Path.new(requested)?
var file = BlockingFile.open(&path)?
let text = file.read_to_string_blocking()?
var frequencies: Map<String, usize> = Map.empty()
var unique: Set<String> = Set.empty()
var line_count: usize = 0
for line in text.lines() {
line_count += 1
let key = String.copy(line)
if frequencies.contains_key(&key) {
frequencies[&key] += 1
} else {
let _ = frequencies.insert(move key, 1)
}
let _ = unique.insert(String.copy(line))
}
let needle = String.copy(requested_needle)
let matching = if frequencies.contains_key(&needle) {
frequencies[&needle]
} else {
0
}
let lines_text = line_count.to_string()
let unique_text = unique.len().to_string()
let matching_text = matching.to_string()
let output = String.concat(
"lines: ",
&lines_text,
"\nunique: ",
&unique_text,
"\nmatching: ",
&matching_text,
"\n",
)
io.print(&output)?
return 0
}