Why can't I delete multiple entries from bash history with this loop
Asked Answered
S

1

5

This loop will display what I want to do but if I remove the echo from it, it won't actually delete anything:

history | grep ":[0-5][0-9] ls *$" | cut -c1-5 | 
while read id; do 
    echo history -d $id
done

I've added indentation in order to make it more readable but I am running it as a one-liner from the command line.

I have HISTTIMEFORMAT set so the grep finds the seconds followed by ls followed by an arbitrary number of spaces. Essentially, it's finding anything in history that's just an ls.

This is using bash 4.3.11 on Ubuntu 14.04.3 LTS

Sublimate answered 18/12, 2015 at 17:4 Comment(0)
M
10

history -d removes an entry from the in-memory history, and you are running it in a subshell induced by the pipe. That means you are removing a history entry from the subshell's history, not your current shell's history.

Use a process substitution to feed the loop:

while read id; do
    history -d "$id"
done < <(history | grep ":[0-5][0-9] ls *$" | cut -c1-5)

or, if your version of bash is new enough, use the lastpipe option to ensure your while loop is executed in the current shell.

shopt -s lastpipe
history | grep ":[0-5][0-9] ls *$" | cut -c1-5 | 
while read id; do 
    echo history -d $id
done
Monk answered 18/12, 2015 at 17:12 Comment(3)
Hmmm, neither seems to work. Though, your explanation on why it doesn't work seems plausible.Sublimate
Oh, right. An earlier version of my command line had a reverse sort to deal with this but I didn't put it in my question. It works fine once I do that.Sublimate
Good :) I deleted my previous comment because I wasn't convinced I had verified it sufficiently.Monk

© 2022 - 2024 — McMap. All rights reserved.