#!/usr/bin/guile !# (use-modules (sph) (sph io) (sph alist) (sph string) (sph cli)) (define lines-filter-cli (let (cli (cli-create #:description "read from standard input and filter lines case-insensitively by given strings or regular expressions" #:options (q ( (negate) (or #:description "matching lines must contain at least one of the strings") (regexp #:names #\r #:description "interpret strings as posix extended regular expressions") (case-sensitive #:names #\c) (and #:description "matching lines must contain all strings. the default") ((strings ...)))))) (nullary (let* ( (arguments (cli)) (regexp? (alist-ref-q arguments regexp)) (case-sensitive? (alist-ref-q arguments case-sensitive)) (patterns (map (if regexp? (if case-sensitive? make-regexp (l (a) (make-regexp a regexp/icase))) (if case-sensitive? identity string-downcase)) (alist-ref-q arguments strings (list)))) (negate? (alist-ref-q arguments negate)) (or? (alist-ref-q arguments or)) (and? (alist-ref-q arguments and))) (if (null? patterns) (port-copy-all (current-input-port) (current-output-port)) (let* ( (match? (if regexp? (if or? string-matches-any-regexp? string-matches-every-regexp?) (if or? string-contains-some? string-contains-all?))) (match-line? (if case-sensitive? (l (line) (match? line patterns)) (l (line) (match? (string-downcase line) patterns))))) (port-lines-each (if negate? (l (line) (if (not (match-line? line)) (display-line line))) (l (line) (if (match-line? line) (display-line line))))))))))) (lines-filter-cli)