#!/usr/bin/env fish # This script filters a file on a given regex, deleting all entries that match. # it is intended to be used with yaml-like files (namely, the fish shell history file) # and will delete entries, not individual lines. To give an example: # - cmd: "cd ~/Documents" # when: 128301283 # - paths: # /usr/bin # - cmd: "mv file file2" # when: 1928321 # with the regex "(^|[^a-z])(Documents)($|[^a-z])" will result in: # - cmd: "mv file file2" # when: 1928321 # (note how it deletes not only the line containing the matched regex, but also the 'when' and 'paths' components). # # the input for this script is: # script.fish Regex File # where: # Regex is the pattern to be matched, and # File is the file to be filtered. # error handling if not test -f "$argv[2]" printf 'Wrong syntax!\nUse:\t%s\tRegex\tFile' "$(basename (status -f))" exit end # setup set -f is_writing "false" set -f tempFile (mktemp -p '' fish_hist.XXXXX) set -f num_deleted 0 # loop through the file while read -lad ' ' line if string match -qri "^- cmd:" -- "$line" if string match -qri "$argv[1]" -- "$line" set is_writing "false" set num_deleted (math $num_deleted + 1) else printf '%s\n' "$line" >> "$tempFile" set is_writing "true" end else if string match -q "true" -- "$is_writing" printf '%s\n' "$line" >> "$tempFile" end end < "$argv[2]" printf 'Discarding %d line(s).\n ' "$num_deleted" # replace files rm "$argv[2]" cp "$tempFile" "$argv[2]"