private static async Task Main(string[] args) { var rootCommand = new RootCommand { Options.Regexp, Options.File, Options.PrintStatistics, Options.Trim, Options.MaxCount, Options.OutputFile }; rootCommand.Description = "Yet another sub-optimal grep implementation."; rootCommand.Handler = CommandHandler.Create <string, FileInfo, bool, bool, int, FileInfo>( async(regexp, file, statistics, trim, maxCount, outputFile) => { var options = new GrepOptions(trim: trim, maxCount: maxCount, captureStatistics: statistics); var result = outputFile == null ? await file.FullName.Grep(regexp, r => WriteLine("[line {0}]{1}", r.LineNumber, r.Line.AsString()), options) : await GrepAndSaveOnFile(file, regexp, outputFile, options); if (statistics) { WriteLine("------------------------"); WriteLine("------ STATISTICS ------"); WriteLine("------------------------"); WriteLine(result); } }); Environment.ExitCode = await rootCommand.InvokeAsync(args); }
public LineReader(StreamReader haystack, GrepOptions options) { _buffer = new char[options.BufferSize]; _haystack = haystack; _options = options; _line = new Line(_buffer, options.Trim); }
private static async Task <GrepStatistics> GrepAndSaveOnFile( FileSystemInfo input, string regexp, FileInfo output, GrepOptions options) { await using var target = File.Create(output.FullName); await using var writer = new StreamWriter(target, Encoding.UTF8) { NewLine = "\n", AutoFlush = true }; return(await input.FullName.Grep(regexp, async r => await r.FlushInto(writer, autoFlush: false), options)); }
public static Func <Line, int, GrepResult> For(string needle, GrepOptions options) { // TODO: regexp support return(NaiveStringContains(needle, options)); }
public static Func <Line, int, GrepResult> NaiveStringContains(string needle, GrepOptions options) => (line, lineIndex) => { var limit = line.Length - needle.Length + 1; if (limit < 1) { return(GrepResult.Failure(line)); } // Store the first 2 characters of the needle var c0 = needle[0]; var c1 = needle[1]; // Find the first occurrence of the first character var possibleMatchStart = line.IndexOf(c0, startSearch: 0, limit); while (possibleMatchStart != -1) { // Check if the following character is the same like the 2nd character of the needle if (line[possibleMatchStart + 1] != c1) { possibleMatchStart = line.IndexOf(c0, ++possibleMatchStart, limit - possibleMatchStart); continue; } var found = true; // Looking for the rest of the needle (starting with the 3rd character) for (var i = 2; i < needle.Length; i++) { if (line[possibleMatchStart + i] != needle[i]) { found = false; break; } } // If the whole word was found, return its index, otherwise try again if (found) { return(GrepResult.Success(line, lineIndex + 1, possibleMatchStart, possibleMatchStart + needle.Length - 1)); } possibleMatchStart = line.IndexOf(c0, ++possibleMatchStart, limit - possibleMatchStart); } return(GrepResult.Failure(line)); };