Jak usunąć wybrane wyniki z historii bash?

66

historypolecenie wyświetla wszystkie wyniki, ale możemy filtrować, aby uzyskać określone polecenie za pomocą history | grep searchingCommand. To jest naprawdę pomocne.

Ale problem polega na tym, że pokazuje te polecenia, które zostały wprowadzone z błędem literówki lub które zakończyły się niepowodzeniem. Zatem znalezienie właściwego jest naprawdę uciążliwe. Sprawdziłem ten link: Selektywna historia poleceń w terminalu? ale to nie było moje rozwiązanie.

Czy istnieje sposób na usunięcie tych poleceń z historii, które były niepoprawne w podanym czasie lub później?

Saurav Kumar
źródło
5
Proszę zmienić przyjętą odpowiedź, są też inne z ponad 100 głosami.
greuze
1
@greuze: Zmieniono na najlepszą odpowiedź. Liczba głosów nie oznacza, że ​​jest najlepsza!
Saurav Kumar,

Odpowiedzi:

20

Chciałbym dodać inną metodę modyfikowania (lub usuwania) wpisów historii, którą znalazłem raczej przypadkowo podczas pracy z bash:

Aby to zademonstrować, zacznij od wykonania następujących trzech poleceń w bash:

$ echo 1
1
$ echo 2
2
$ echo 3
3

Możesz teraz ponownie wybrać te polecenia za pomocą klawiszy strzałek lub Ctrl+ pi Ctrl+ n.

Powiedz, że chcesz zmodyfikować pierwsze dwa polecenia. Poruszaj się po historii, aż echo 1pojawi się i zmień ją na echo 1 - changed, ale NIE NACISNĄĆ ENTER. Jeśli teraz przejdziesz dalej w swojej historii, linia ta pozostanie w zmodyfikowanym stanie i możesz się do niej wycofać i wrócić. Teraz przejdź do linii echo 2i zmień na echo 2 - changed, ponownie nie naciskaj enter. Aby zapisać zmiany w tych wierszach, wybierz dowolne polecenie w historii oprócz tych dwóch i naciśnij Ctrl+ c.

Oczywiście zamiast modyfikować wpis historii, możesz go również usunąć, co spowoduje powstanie pustego wiersza przy tym wpisie. Aby usunąć wiersz aktualnie wyświetlany w wierszu polecenia, naciśnij Ctrl+ e(który przeskakuje na koniec linii), a następnie Ctrl+ u(co usuwa tekst od początku linii do kursora).

Zobacz także https://unix.stackexchange.com/questions/195668/what-can-cause-an-item-to-be-deleted-from-my-bash-history/195726#195726, aby uzyskać bardziej szczegółowe wyjaśnienie zaplecze techniczne.

Najprostszy sposób:

  1. ctrl+, raby wyszukać polecenie, które chcesz usunąć / zmodyfikować.
  2. end aby wybrać szukane polecenie do usunięcia / modyfikacji
  3. Usuń lub zmodyfikuj wybrane polecenie (nie naciskaj enterani ctrl+ c)
  4. strzałka w górę (lub ctrl+ p) lub strzałka w dół (lub ctrl+ n), aby wybrać dowolne inne polecenie.
  5. ctrl+ c To wszystko!

Uwaga :

Zmienia to tylko bieżące polecenia sesji. Jeśli chcemy zmienić starsze polecenia i zapisać zmiany, musimy uruchomić następujące polecenie przed zamknięciem terminala:

history -w
Stefan Hamcke
źródło
Wielkie dzięki Stefan! Muszę powiedzieć, że przyniosłeś niesamowite rzeczy. Korzystając z tego, znalazłem najprostszy sposób na modyfikację / usunięcie historii: 1.ctrl+r aby wyszukać polecenie, które chcesz usunąć / zmodyfikować. 2.end aby przenieść polecenie i usunąć / zmodyfikować polecenie. 3.ctrl+n przejść do następnej linii, a następnie 4.ctrl+c
Saurav Kumar
144

Posługiwać się:

history -d OFFSET

aby usunąć pozycję historii z przesunięciem, OFFSETnawet zanim została dodana do pliku historii bash. Aby znaleźć właściwe OFFSET, wystarczy uruchomić historypolecenie. Jest to liczba od początku wiersza, która zawiera wpis historii, który chcesz go usunąć.

Aby zapisać zmiany w historii, użyj:

history -w

Zobacz więcej szczegółów w tym przewodniku .

użytkownik299481
źródło
nieźle :) Dobrze jest dostać nowy sposób ..
Saurav Kumar
10
@SauravKumar Nieźle?!? Prawdopodobnie jest to najlepszy sposób ...
Radu Rădeanu
5
PRZECZYTAJ PIERWSZE: Żeby było jasne, musisz zrobić history -wposłowie, aby zapisać zmiany. Również PRZESUNIĘCIE oznacza historywyświetlaną liczbę . Jeśli linia, którą próbujesz usunąć, to 873, użyj history -d 873.
Cammy_the_block
2
@ RaduRădeanu Użyj history -wpo, history -daby zapisać zmiany.
Cammy_the_block
20
To powinna być poprawna odpowiedź.
topher
19

Edytuj plik ~/.bash_historyi usuń raz za pomocą literówek

Na przykład wstaw to polecenie:

gedit ~/.bash_history

Edytuj coś, co lubisz, a następnie zapisz plik i uruchom ponownie terminal. Polecenie root to:

sudo -i 
inser your password
gedit ~/.bash_history

jeśli chcesz usunąć wszystko history -c, załatw sprawę


SKŁADNIA

history
history [n]
history -c
history -d offset
history [-anrw] [filename]
history -ps arg

KLAWISZ

-c Wyczyść listę historii. Można to połączyć z innymi opcjami, aby całkowicie zastąpić listę historii.

-d offset Usuń wpis historii w przesunięciu pozycji. Przesunięcie należy określić tak, jak jest wyświetlane, gdy wyświetlana jest historia.

-a Dołącz nowe linie historii (linie historii wprowadzone od początku bieżącej sesji Bash) do pliku historii.

-n Dołącz linie historii, które nie zostały jeszcze odczytane z pliku historii do bieżącej listy historii. Są to linie dołączane do pliku historii od początku bieżącej sesji Bash.

-r Przeczytaj bieżący plik historii i dołącz jego zawartość do listy historii.

-w Zapisz bieżącą historię do pliku historii.

-p Wykonaj podstawienie historii dla argumentów i wyświetl wynik na standardowym wyjściu, bez zapisywania wyników na liście historii.

-s Argumenty są dodawane na końcu listy historii jako pojedynczy wpis.

źródło :

blade19899
źródło
Dzięki, to jest pomocne! Czy wiesz, jak usunąć wpis w momencie wprowadzenia go z wiersza poleceń? Czy istnieje polecenie usunięcia wpisu bez otwierania .bash_history?
Saurav Kumar,
1
@ bladed19899 history -cnie działa Kiedy zamykam terminal i otwieram go ponownie, historie nie są usuwane. -1 twoja odpowiedź
αғsнιη
1
@KasiyA, -c Clear the history list. This may be combined with the other options to replace the history list completely. źródło
blade19899
2
@KasiyA Użyj history -wpo, history -caby zapisać zmiany.
Cammy_the_block
16

Jeśli chcesz natychmiast usunąć go z tego samego terminala, musisz najpierw dodać do pliku ~ / .bashrc.

PROMPT_COMMAND='history -a' 

i uruchom ponownie terminal.

Możesz dodać go w dowolnym miejscu w pliku .bashrc. Dodałem jak poniżej wraz z innymi rzeczami związanymi z historią.

wprowadź opis zdjęcia tutaj

Zwykle podczas sesji bash wykonywane polecenia nie są zapisywane w .bash_history, dopóki sesja nie zostanie zakończona, a PROMPT_COMMAND='history -a'następnie wprowadza polecenie wtedy i tam w .bash_history.

Teraz, gdy popełnisz błąd lub błąd w poleceniu i chcesz go usunąć wtedy i tam, po prostu wykonaj następujące czynności

sed -i '$d' ~/.bash_history

i tada zostanie usunięty.

Aby to uprościć, możesz dokonać aliasu na coś prostszego i użyć go, np

alias rh ='sed -i '\''$d'\'' ~/.bash_history'

Wykonanie rhusunie ostatnio wykonane polecenie z historii.

Powyższe jest tymczasowym aliasingiem, który trwa tylko dla sesji. Aby dodać go na stałe lub na stałe

alias rh = 'sed -i '\''$d'\'' ~/.bash_history' 

do .bashrc

UWAGA

Po obu stronach nie powinno być miejsca =

Jeśli nie chcesz aliasu, możesz wykonać następujące czynności

Stwórz nazwę commada rhi umieść ją w /binkatalogu:

  • Otwórz plik powiedz rhi wklej następujący kod, zapisz i zamknij:

    sed -i '$d' ~/.bash_history

  • Udostępnij rhplik wykonywalny i umieść go w /binkatalogu:

     chmod + x rh
     sudo cp rh / bin 
  • Teraz użyj rhpolecenia, aby usunąć ostatnie polecenie z historii.

Stormvirux
źródło
Gdzie dodać PROMPT_COMMAND='history -a'w .bashrcpliku? A co dokładnie zrobi? Próbowałem sed -i '$d' ~/.bash_historyto działa bez edycji .bashrc!! Ale alias nie działa. Przyjmę twoją odpowiedź, jeśli tylko opracujesz moje pytanie i sprawisz, że alias będzie działał .. :)
Saurav Kumar
@SauravKumar zredagował odpowiedź. Brakowało pojedynczego i podwójnego cudzysłowu w poleceniu aliasingu. Mój zły ..: P
Stormvirux
Uwierz mi lub nie ... alias nadal nie działa .. Wykonuje się bez żadnego błędu, ale nie usuwa wpisu z .bash_historypliku ..: P w jakikolwiek sposób .. Nie ma problemu .. Wykonałem własne polecenie i umieściłem je w /bininformator. Ponieważ z twojego polecenia: sed -i "$d" ~/.bash_historydziała dobrze. Przyjmuję twoją odpowiedź .. :)
Saurav Kumar,
Jeśli nie masz nic przeciwko, chciałbym edytować twoją odpowiedź, aby była pomocna dla innych ..
Saurav Kumar
Właściwie to go edytowałem. Musisz to zatwierdzić ..
Saurav Kumar,
2

aby usunąć wiele linii (np. od 1974 do 1990, sprawdź historypoleceniem):

  for i in `seq 1974 1990` ; do history -d 1974 ; done

zwróć uwagę, że numer wiersza do usunięcia jest zawsze taki sam, ponieważ usuwasz go stale i przechodzisz do następnego.

törzsmókus
źródło
Uwaga jest bardzo ważna.
Weijun Zhou
1

Jeśli używasz opcji „set -o vi” w bash (bardzo przydatne do wyszukiwania wstecz za pomocą klawisza Escape), możesz wyszukać linię i usunąć linię za pomocą „dd” w taki sam sposób jak w „vi”.

Facet IT
źródło
Uważam, że muszę wpisać jlub kpóźniej, ddaby faktycznie usunąć polecenie z historii. Jeśli wpisuję inne polecenie lub po prostu naciskam Enter, bash wydaje się zakładać, że jest to po prostu nowe polecenie i że powinno ono zachować stare polecenie w historii. Interesujące jest również zauważyć, że gdy jest wykonane poprawnie, usuwa polecenie, ale go nie usuwa - wynikiem są puste wpisy historii. Jest to jednak wystarczające do usuwania haseł, które musiałem wpisać w wierszu poleceń, i znacznie łatwiejsze niż inne odpowiedzi, więc bardzo dziękuję za opublikowanie tego!
Michael Scheper,
0

Miałem sytuację, w której miałem zbędne wpisy w mojej historii bashów od Yubikey - może około 50, pasujące do „ccccc .....”. Idealnie chciałem znaleźć sposób na usunięcie wpisów pasujących do wzorca, co, jak sądzę, można zrobić z sed lub czymś podobnym, zakładając, że Twoja historia ignoruje puste.

W każdym razie stałem się leniwy i skończyło się na tym, że korzystałem z vima, szukając „cccc” i używając „dd” podczas przeglądania każdego meczu. Nie trwało to dłużej niż minutę.

Dylan_Larkin
źródło
1
Jeśli robisz to w vimie, możesz również zrobić: g / cccc / d lub: g / ^ cccc / d: lub użyć makra qqnddq, a następnie @@ (zakłada, że ​​twoje ostatnie wyszukiwanie dotyczyło ccccc).
htaccess
@htaccess To z pewnością byłoby łatwiejsze, ale chciałem wizualnie sprawdzić resztę pliku w tym samym czasie.
Dylan_Larkin