bashloopsfor-loopcommand-history

How to delete history in a range in linux bash


Fooling around with Linux on my Pi and ran into this problem. I found that you can remove a certain line with the command history -d linenumber but what if I want to remove a range (which I think is much more practical)? So I looked up how to loop in several places. Both ways of looping worked for an echo but not for the history command. I think it's because "history" is not actually a command. But why does this matter? Is there a simple way of doing this? I never knew looping was possible in Linux bash so now I'm pretty curious! Here's what I did:

pi@raspberry:~$ for ((i=258;i<=262;++i)); do "history -d $i"; done; // which is incorrect due to quotes, giving: -bash: history -d 258: command not found -bash: history -d 259: command not found -bash: history -d 260: command not found -bash: history -d 261: command not found -bash: history -d 262: command not found

This below should work (but it doesn't):

pi@raspberry:~$ for i in {5..10}; do history -d $i; done; -bash: history: 5: history position out of range

I found an article here: https://superuser.com/questions/649859/history-position-out-of-range-when-calling-history-from-bash-script

... but they were not clear at all and said something along the lines that it needs to be sourced instead of executed, which actually means nothing to me. If it can't be done through the command line just say so. Otherwise, I am going to be brushing up on Python, and if that's a logical way of doing it, it'd be nice to know.

Thanks


Solution

  • for ((i=258;i<=262;++i)); do "history -d $i"; done;
    

    as you said, is simply not working due to quotes

    for i in {5..10}; do history -d $i; done;
    

    is working, but you must ensure to have entries from 5 to 10, which in your examples, you don't have.
    Take into account that every item you remove, the position indexes of the other items scale down of one.

    Basically you should reverse loop items:

    for i in {10..5}; do history -d $i; done;
    

    to not be affected by the position index changes while looping.

    Edit
    As Cyrus suggested, there's another approach.
    You want to remove items from 258 to 262, a total of 5 entries (262 is included)
    You can delete 5 times the entry at position 258.
    Taking advantage of the index scaling down of one every time you delete an item: