Last active
July 5, 2022 10:38
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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