Skip to content

Instantly share code, notes, and snippets.

@ebresafegaga
Last active July 5, 2022 10:38
Show Gist options
  • Save ebresafegaga/dbd6b6f167a3c3291558a8b469213c01 to your computer and use it in GitHub Desktop.
Save ebresafegaga/dbd6b6f167a3c3291558a8b469213c01 to your computer and use it in GitHub Desktop.
I'd rather write grep in OCaml. Just a small utility to search the output of `ls -R`, and then search each file. Basically searching all files in a directory for a particular "key" (or filtering some files out)
let (>>) f g a = a |> f |> g
let input_lines file =
let rec loop chan =
match input_line chan with
| line -> line :: loop chan
| exception End_of_file -> []
in
let chan = open_in file in
let result = loop chan in
close_in chan;
result
let input_string = input_lines >> String.concat "\n"
let contains s2 s1 =
let re = Str.regexp_string s2
in
try ignore (Str.search_forward re s1 0); true
with Not_found -> false
let base = "<your source directory here>"
module Parsing = struct
type result = (string * string list) list
let parse (str: string) : result =
let tuple = function
| [] -> failwith "parse error"
| first :: rest -> first, rest in
let toplevel group =
match group with
| [] -> false
| first :: _rest -> first.[String.length first - 1] <> ':' in
let trim group =
match group with
| [] -> []
| first :: rest -> String.sub first 0 (String.length first - 1) :: rest in
str
|> Str.split (Str.regexp "\n\n")
|> List.map (fun group ->
let group = group |> Str.split (Str.regexp "\n") in
if toplevel group then tuple ("." :: group) else tuple (trim group))
end
module Filtering = struct
type result = string list
let filter (presult: Parsing.result) : result =
let right file = file = "Makefile" || file = "makefile" in
presult
|> List.concat_map (fun (dir, files) ->
files
|> List.concat_map (fun file ->
if right file then
[Filename.concat base @@ Filename.concat dir file]
else []))
end
module Searching = struct
type result = string list
let key = "build-release-archives.sh"
let find : Filtering.result -> result =
(* 1. open up the file (for each entry, i.e filename)
2. assume it's one big string
3. find the `key` in the string
4. if the key is present in the string, leave this entry, else filter it out*)
List.filter (input_string >> contains key)
end
let finder = input_string >> Parsing.parse >> Filtering.filter >> Searching.find
let () =
Sys.argv.(1)
|> finder
|> List.iter print_endline
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment