summaryrefslogtreecommitdiff
path: root/.local/bin/filter
diff options
context:
space:
mode:
Diffstat (limited to '.local/bin/filter')
-rwxr-xr-x.local/bin/filter52
1 files changed, 52 insertions, 0 deletions
diff --git a/.local/bin/filter b/.local/bin/filter
new file mode 100755
index 0000000..9d3e5e3
--- /dev/null
+++ b/.local/bin/filter
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+help() { echo "filter - filter input based on given expression to evaluate
+
+USAGE:
+ filter [OPTION]... <FILTER_EXPRESSION> [FILES]...
+
+OPTIONS:
+ -i update files with filtered content
+ -h show this help message
+
+FILTER_EXPRESSION is a contains the command string that will be executed to test
+the input line. {} should be used as a placeholder that will be replaced to the
+double-quoted string of the input line. If the command evaluates to true, the
+line is printed to stdout.
+"; }
+
+err() { printf 'filter: %s\n' "$@" >&2; exit 1; }
+while getopts 'ih' o; do case "$o" in
+ i) iflag=1 ;;
+ h) help; exit ;;
+ *) err "invalid option -- '$OPTARG'" ;;
+esac done
+shift $((OPTIND - 1))
+
+[ "$#" -lt 1 ] && help >&2 && exit 1
+filter="$1"; shift
+
+evaluate() {
+ while IFS= read -r line; do
+ escaped_line="$(printf "%s\n" "$line" | sed "s|\"|\\\\\\\\\"|")"
+ cmd="$(printf "%s\n" "$filter" | sed "s|{}|\"$escaped_line\"|")"
+ eval "$cmd" && printf "%s\n" "$line"
+ done
+}
+
+if [ "$iflag" = 1 ]; then
+ for file in "$@"; do
+ [ -z "$1" ] && err "option -i requires file argument and none were passed"
+ tmp="$(mktemp "/tmp/$file.tmp-filter.XXXXXX")"
+ evaluate < "$file" > "$tmp"
+ mv "$tmp" "$file"
+ done
+ exit
+fi
+
+if [ -n "$1" ]; then
+ evaluate < "$@"
+else
+ evaluate
+fi
+