Skip to content

Instantly share code, notes, and snippets.

@sleekweasel
Last active October 30, 2025 16:55
Show Gist options
  • Select an option

  • Save sleekweasel/a415fd1c5f80f79ec370d1d341340faf to your computer and use it in GitHub Desktop.

Select an option

Save sleekweasel/a415fd1c5f80f79ec370d1d341340faf to your computer and use it in GitHub Desktop.
A copy-pasteable shell-based interactive line editor, for when I don't have vim in a container and don't want to install it for some reason.
#!/bin/bash
# Deliberately compact for easy copy/paste install
set -o nounset -o errexit -o pipefail
trap 'echo Aborted. Renaming "$EDIT" with appended date ; set -x ; mv -n -- "$EDIT" "$EDIT$(date +%F.%T)" || : ; exit 42' INT TERM
if ! [[ -f "$1" ]] ; then echo "Usage: $0 file-to-edit. Did not see file '$1'" ; exit 42 ; fi
FILE="$1"; EDIT="$1~"
if [[ -f "$EDIT" ]] && ! diff -u -- "$FILE" "$EDIT" ; then
echo Resolve or ignore above diffs. Quitting. ; echo "rm $EDIT" ; exit 42
fi
cp "$FILE" "$EDIT"
help() { echo "Try" ; grep -E ') *#' -- "$0" ; echo "And ^d to abort" ; }
unodiff() { diff -u -- "$1" "$2" && echo (no diff) || echo (diff ends) ; }
help
while IFS= read -erp ':' REPLY || : ; do
case "$REPLY" in
d*) # e.g. d - diff vs original
unodiff "$FILE" "$EDIT" ;;
p*|.p*) # e.g. p or p 10 or p 4,6 or p /hello/ - print line/s
cat -n -- "$EDIT" | sed -n "${REPLY#*p} p" ;;
s\ *) # e.g. s 4,6 s/find/replace/ s!a/b!c/d! (any sed command like 's 5d' or 's 5i insert-before' or 's 5a insert-after' with \ for leading space )
TMP=$(mktemp) ; sed -- "${REPLY#s}" "$EDIT" > "$TMP" || : ; unodiff "$EDIT" "$TMP" ; mv -- "$TMP" "$EDIT" ;;
i\ *) # e.g. i 18 - multiline insert before line 18
echo "Type multiple lines starting with the new line, end with ^D"
TMP=$(mktemp) ; n=$(( ${REPLY#i } )) ; ( (( n > 1 )) && head -n "$((n-1))" -- "$EDIT" || : ; cat ; tail -n "+$n" "$EDIT" ) > "$TMP"
unodiff "$EDIT" "$TMP" ; mv "$TMP" "$EDIT" ;;
qs*|sq*|wq|:wq) # Quit and save
echo "Saving $EDIT to $FILE" ; mv -- "$EDIT" "$FILE" ; exit 0 ;;
qq*) # Quit without saving
echo "Quit without saving. Renaming $EDIT with appended date" ; set -x ; mv -- "$EDIT" "$EDIT$(date +%F.%T)" ; exit 1 ;;
'') ;;
*)
echo "Don't know '$REPLY'" ; help ;;
esac
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment