-1

I'm working with my .bash_history file and want to identify repetitive commands for cleanup.

Here's a sample snippet:

...
#1713251479
sh lowbat.sh
#1713251495
nvim lowbat.sh
#1713252186
sh lowbat.sh
#1713253121
xclip -sel clip lowbat.sh
#1713253722
cd code/dotfiles/
#1713253766
git add mpv/
...

My goal is to:

  1. Sort the commands alphabetically to easily identify redundant entries.
  2. Review and edit the sorted list (in the .bash_history_sorted file) to omit unnecessary commands.
  3. Restore the original order (sorted by timestamps) in the .bash_history_sorted file and finally overwrite the original .bash_history file with .bash_history_sorted file.

Can this be achieved using the sort command?

EDIT: I ended up writing my own program in C language. Here's the source code, although I'm still open to other approaches.

2
  • Search for: HISTCONTROL, HISTFILESIZE and HISTIGNORE in the Bash manual. With export HISTCONTROL=ignoreboth, both commands starting with space and duplicates are not saved. Commented May 10, 2024 at 21:10
  • By duplicate command, I don't mean exact duplicate, but slight changes in the same command, so I have to check it manually. Commented May 11, 2024 at 0:05

1 Answer 1

1

Given 1 line per command as in your posted sample input, this Decorate-Sort-Undecorate approach will work using any awk, sort, etc.:

$ cat tst.sh
#!/usr/bin/env bash

tmp1=$(mktemp) || exit 1
tmp2=$(mktemp) || exit 1
trap 'rm -f "$tmp1" "$tmp2"; exit' EXIT

infile="$1"

awk '/^#/{t=$0; next} {print t, NR "\t" $0}' "$infile" |
sort -k3 > "$tmp1" &&
"${EDITOR:-vi}" "$tmp1" &&
sort -k2,2n "$tmp1" |
awk '{print $1; sub(/^[^\t]+\t/,""); print}' > "$tmp2" &&
{ diff "$infile" "$tmp2" || true; } &&
IFS= read -r -p 'Overwrite input file [y/n]? ' rsp &&
[[ $rsp =~ ^[yY] ]] &&
cp -- "$infile" "${infile}.bk" &&
mv -- "$tmp2" "$infile"

Call it as tst.sh .bash_history and only reply y to the final prompt once you're done testing and happy that it does what you want. It will create a backup file, e.g. .bash_history.bk, of the input too though in case you need it.

Use a hard-coded file name of .bash_history_sorted instead of "$tmp2" and/or a hard-coded .bash_history instead of "$1" if you prefer.

If you're not sure what it does, just run the first awk command on it's own to see what that does, then add the pipe to the first sort and see what that does, and so on.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.