Reputation: 36
Question: I'm trying to create a Bash script that deletes a specified number of entries from the history, starting from a given position. The idea is to make it easier to clean up portions of the history interactively.
What I've tried:
for loop
using history -d
to delete the entries in a range, but I faced issues with history line shifts during the deletion process..bashrc
, to ensure the history could be accessed directly in the interactive shell. While this allowed me to delete entries, the function didn’t handle larger ranges correctly or threw "history position out of range" errors.history -a
and history -r
before and after deletion commands to keep the entries synced. This also yielded inconsistent results, particularly when I tried to delete from specific positions in larger history ranges.Current Challenge: The main issue is that the script either fails to delete the specified number of lines accurately or doesn’t start deleting from the correct position due to shifts in history entries. I’d appreciate any guidance on how to create a stable Bash script that consistently deletes a chosen number of lines starting at a specified history position.
What I Tried:
history -d
: I attempted to use a for
loop with history -d
to delete a specific range of entries. For example, starting from a certain position in history, I tried deleting the next specified number of lines. However, I encountered issues with the history line numbers shifting as entries were deleted, which made the loop unreliable.Here’s one of the versions I tried using a for loop with history -d, starting from a given history position:
N=10 # Number of lines to delete
START=50 # Starting position
for ((i=N-1; i>=0; i--)); do
history -d $((START + i))
done
This approach didn’t work as expected because the history line numbers shift each time an entry is deleted, which makes the loop unreliable.
.bashrc
: To keep the script within the interactive shell, I moved it to .bashrc
as a function, assuming that working directly with the shell's history would improve reliability. This allowed partial deletion, but it still failed to delete the exact number of entries and sometimes returned "history position out of range" errors.I also tried adding the script as a function directly in .bashrc
:
delete_history_range() {
local N=$1
local START=$2
for ((i=N-1; i>=0; i--)); do
history -d $((START + i))
done
}
This allowed me to call the function interactively, but I faced issues with larger ranges, and sometimes I got "history position out of range" errors.
history -a
and history -r
: I also tried adding history -a
(to append recent commands to the history file) and history -r
(to reload it) before and after each deletion command. This aimed to keep the history synced with the shell's current session, but it produced inconsistent results, particularly with larger ranges.What I Expected:
I expected a non-interactive solution that could delete an exact number of entries from history, starting at a given position, without manual input. Ideally, the script would reliably handle shifts in line numbering as entries are deleted, without causing out-of-range errors.
Ps.: I came across this question on Stack Overflow, which addresses deleting the last entry in the Bash history with a script. However, my question is a bit different: I’m looking for a way to delete a specific range of entries from history, starting at a given position.
I've tried various approaches, but due to history line shifts and "out of range" errors, I'm struggling to find a reliable solution. While the other question helped me understand how history -d works for single entries, I need a solution that can handle deleting multiple entries in a specified range, starting from an arbitrary point in the history.
Upvotes: 1
Views: 79
Reputation: 181
By using a combination of tail and head you should achieve it
Use head by getting all but the X last line of a file named file.txt .
head -n -X file.txt
It should work for .bash_history too and this could do the trick ?
head -n -X .bash_history > .bash_history
Use tail to keep the Y last line of a file named file.txt .
tail -n Y file.txt
you could combine this to have a script that create 2 temp files then merge them to .bash_history
Upvotes: 0
Reputation: 12822
Deleting entries in reverse order avoids the line shifting issue since the lines will be shifted below the highest entry (the first deleted) in the range but not the others
for i in $(seq 1734 -1 1729); do history -d "$i";done
to print a range of history entries
fc -l 1729 1734
Using OP's for loop and starting at the highest record
N=6; START=1734; for ((i=START; i>((START-N)); i--)); do echo "Deleting history event #$i"; history -d $i; done
Out
Deleting history event #1734
Deleting history event #1733
Deleting history event #1732
Deleting history event #1731
Deleting history event #1730
Deleting history event #1729
Upvotes: 0