Last active 1719877009

Find a pattern in a file, print the content of the file and mark the position of the pattern (if found)

adridoesthings's Avatar adridoesthings revised this gist 1719877009. Go to revision

No changes

adridoesthings's Avatar adridoesthings revised this gist 1719876998. Go to revision

1 file changed, 80 insertions

find.zig(file created)

@@ -0,0 +1,80 @@
1 + const std = @import("std");
2 +
3 + const COLOR_RED = "\x1b[0;31m";
4 + const COLOR_RESET = "\x1b[0m";
5 +
6 + fn print_usage(exec: [*:0]u8) void {
7 + std.debug.print("Usage: {s} FILE PATTERN\n", .{exec});
8 + }
9 +
10 + fn string_contains_substring(allocator: std.mem.Allocator, string: []u8, substring: []u8) !std.ArrayList([2]usize) {
11 + var list = std.ArrayList([2]usize).init(allocator);
12 +
13 + var start: ?usize = null;
14 + var substring_index: usize = 0;
15 +
16 + for (string, 0..) |c, i| {
17 + if (c == substring[substring_index]) {
18 + substring_index += 1;
19 +
20 + if (substring_index == substring.len) {
21 + try list.append(.{ start orelse i, i });
22 + start = null;
23 + substring_index = 0;
24 + continue;
25 + }
26 +
27 + if (start == null) {
28 + start = i;
29 + }
30 + } else if (start != null) {
31 + start = null;
32 + substring_index = 0;
33 + }
34 + }
35 +
36 + return list;
37 + }
38 +
39 + pub fn main() !void {
40 + if (std.os.argv.len != 3) {
41 + print_usage(std.os.argv[0]);
42 + std.process.exit(1);
43 + unreachable;
44 + }
45 +
46 + const stdout = std.io.getStdOut().writer();
47 +
48 + var gpa = std.heap.GeneralPurposeAllocator(.{}){};
49 + const allocator = gpa.allocator();
50 + defer {
51 + const status = gpa.deinit();
52 + if (status == .leak) @panic("there are leaks");
53 + }
54 +
55 + const args = try std.process.argsAlloc(allocator);
56 + defer std.process.argsFree(allocator, args);
57 +
58 + const file = try std.fs.cwd().openFile(args[1], .{});
59 + defer file.close();
60 +
61 + const reader = file.reader();
62 + while (true) {
63 + const line = reader.readUntilDelimiterAlloc(allocator, '\n', 1024 * 1024) catch break;
64 + defer allocator.free(line);
65 + const contains = try string_contains_substring(allocator, line, args[2]);
66 + defer contains.deinit();
67 +
68 + if (contains.items.len == 0) {
69 + try stdout.print(" {s}\n", .{line});
70 + } else {
71 + try stdout.print("> ", .{});
72 + var previous: usize = 0;
73 + for (contains.items) |element| {
74 + try stdout.print("{s}{s}{s}{s}", .{ line[previous..element[0]], COLOR_RED, line[element[0] .. element[1] + 1], COLOR_RESET });
75 + previous = element[1] + 1;
76 + }
77 + try stdout.print("{s}\n", .{line[previous..]});
78 + }
79 + }
80 + }
Newer Older