#!/bin/sh set -eu usage() { printf 'Usage: %s -p PROFILE -c "COMMAND"\n' "$0" } help() { cat <&2 ;; esac done if [ -z "$COMMANDFLAG" ]; then missing '-c "COMMAND"' >&2 usage >&2 exit 2 fi if [ -z "$PROFILEFLAG" ]; then missing '-p PROFILE' >&2 usage >&2 exit 2 fi COMMAND="$COMMANDFLAG" PROFILE="${XDG_DATA_HOME:-$HOME/.local/share/remembering}/$PROFILEFLAG" if [ ! -e "$PROFILE" ]; then mkdir -p "$(dirname "$PROFILE")" touch "$PROFILE" fi MERGED="$(mktemp)" FILTERED="$(mktemp)" SORTED_STDIN="$(mktemp)" cat - > "$SORTED_STDIN" # sed line to reverse lines, replacing GNU/Linux's tac # Taken from: # https://unix.stackexchange.com/questions/280685/reverse-sequence-of-a-file-with-posix-tools/280686#comment601716_280686 xargs -I{} printf '0:%s\n' "{}" < "$SORTED_STDIN" | \ sort -t: -k2,2 -m - "$PROFILE" | \ sed '1!x;H;1h;$!d;g' | \ sort -t: -k2,2 -u > "$MERGED" xargs -I{} printf 'filter_marker:%s\n' "{}" < "$SORTED_STDIN" | \ cat - "$PROFILE" | \ sort -t: -k2,2 | \ awk '{ split($0, l, ":") rank = l[1] entry = substr($0, length(rank) + 2) if (rank != "filter_marker") { prev_rank = rank prev_entry = entry } else { if (prev_entry == entry) { print prev_rank ":" entry } else { print "0:" entry } } }' > "$FILTERED" CHOICE="$(sort -t: -k1nr,1 -k2,2 < "$FILTERED" | \ cut -d: -f2- | \ sh -c "$COMMAND")" if [ -n "$CHOICE" ]; then NEW_PROFILE="$(mktemp)" awk -v choice="$CHOICE" '{ split($0, l, ":") rank = l[1] entry = substr($0, length(rank) + 2) if (entry == choice) { # Naively increment ranking by one print rank + 1 ":" entry } else { print rank ":" entry } }' "$MERGED" > "$NEW_PROFILE" mv "$NEW_PROFILE" "$PROFILE" printf '%s\n' "$CHOICE" fi