Wyszukaj poprzednie polecenie z przedrostkiem, który właśnie wpisałem

67

Możemy używać strzałek w górę i w dół, aby poruszać się po historii poleceń.

W niektórych IDE, takich jak Matlab, jeśli coś wprowadzimy, a następnie naciśniemy klawisze strzałek, przewijamy tylko polecenia historii, zaczynając od tego, co mamy. To naprawdę wygodne, ale w terminalu powłoki to nie działa.

Czy jest jakiś sposób na uzyskanie podobnej funkcji w terminalu powłoki? I jakieś inne wskazówki dotyczące poprawy wydajności w użyciu terminala?

Zawietrzny
źródło
Możesz po prostu użyć powłoki, która zapewnia taką funkcję, jak fish;)
yoann
@yoann zakładasz, że bash nie. Przez readline po prostu domyślnie nie jest dostępne.
muru
@muru Jestem świadomy CTRL + R w bash, a odpowiedź egmonta zapewnia dobry sposób na zrobienie tego za pomocą Page Up / Page Down. Czy można jednak to zrobić za pomocą klawiszy strzałek?
yoann
1
@yoann sprawdź unix.stackexchange.com/a/76591/70524 . Zamiast \e[5~a \e[6~, użytkowania \e[A, \e[B.
muru

Odpowiedzi:

95

To czego szukasz CtrlR.

Wpisz, CtrlRa następnie wpisz żądaną część polecenia. Bash wyświetli pierwsze pasujące polecenie. Kontynuuj pisanie, CtrlRa bash przejdzie przez poprzednie pasujące polecenia.

Aby wyszukiwać wstecz w historii, wpisz CtrlSzamiast tego. (Jeśli CtrlSto nie działa, oznacza to prawdopodobnie, że musisz wyłączyć kontrolę przepływu XON / XOFF: aby to zrobić, uruchom stty -ixon.)

Jest to udokumentowane w części „Wyszukiwanie” w man bash.

John1024
źródło
1
Ctrl-Qwyjść z zamrożonego stanu, jeśli już uderzyłeś, Ctrl-Snie wyłączając najpierw kontroli przepływu, a terminal został zamrożony.
HongboZhu
26

Umieść je w ~/.inputrc:

"\e[5~": history-search-backward
"\e[6~": history-search-forward

Tworzą Page Upi Page Downzachowują się tak, jak chcesz. (Niektóre dystrybucje już to skonfigurowały.) Osobiście uważam, że te sposoby są wygodniejsze niż Ctrl+ Rlub history.

egmont
źródło
Jest to najwygodniejszy sposób we wszystkich aktualnych odpowiedziach. Czy mógłbyś udzielić trochę wyjaśnień na temat działającego mechanizmu?
Lee
3
~/.inputrclub /etc/inputrcplik, do którego odwołuje się zmienna środowiskowa, $INPUTRCto plik konfiguracyjny do edycji linii wszystkich aplikacji korzystających z readline, w tym bash (twoja powłoka). Ma pewne wbudowane możliwości edycji linii, w tym te dwa: w ręcznym wyszukiwaniu stron bash jednego z tych słów kluczowych, aby dowiedzieć się więcej. \e[5~/ \e[6~to sekwencje specjalne generowane przez klawisze Page Up / Down w większości emulatorów terminali; aby go zobaczyć, uruchom catpolecenie, a następnie naciśnij te klawisze (bajt Escape jest reprezentowany w terminalu jako ^[, w inputrc as \e).
egmont
Przykład w twoim pierwotnym pytaniu mówi, że klawisze góra / dół działają w ten sposób w Matlabie. Interesujące byłoby zobaczyć, co się stanie, jeśli umieścisz sekwencję Up i Down w inputrc i przypiszesz do tej akcji; czy działałoby to poprawnie, czy miałoby nieprzyjemne skutki uboczne, ponieważ koliduje z ich domyślnym zachowaniem Nie wiem, chętnie usłyszę twoje odkrycia, jeśli eksperymentujesz z tym.
egmont
Kiedy to zrobię echo $INPUTRC, jest puste. Używam Ubuntu 14.04
JorgeeFG
2
Osobiście wolę "\e[A": history-search-backward"\e[B": history-search-forward
przesłonić
9

Oprócz historii i-search ^ r / ^:

alt.wstawia ostatnie „słowo” poprzedniego polecenia pod kursorem. Powtórz to, aby uzyskać ostatnie słowo ze starszych poleceń. (Zauważ jednak, że &ostatni znak jest ostatnim słowem dla poleceń w tle).

Jest to bardzo przydatne dla mkdir foo, cdAlt-kropka. Nawet szybciej niż strzałka w górę ^ a, alt-d (usuwanie naprzód słowo) cd.

Aby uzyskać słowo od drugiego do ostatniego, użyj esc - 2 alt+.(tzn. Użyj argumentu numerycznego w stylu emacsa do alt+.. Negatywne liczy się od końca, pozytywne liczy się od początku.) Ale to zwykle jest więcej kłopotów niż jest warte; w pewnym momencie szybciej jest sięgnąć po mysz i skopiować / wkleić lub strzałkę w górę i ^ w / ^ y jej część (patrz poniżej).


Jeśli twój terminal jest skonfigurowany ładnie / poprawnie, ctrl-lewy i ctrl-prawy będą przewijać słowa do tyłu / do przodu. Jeśli nie, mam nadzieję, że przynajmniej Alt-B i Alt-F zrobią to samo.


ctrl- / jest cofnięciem. Możesz użyć automatycznego powtarzania do usuwania słów o wiele bardziej efektywnie, jeśli możesz cofnąć, gdy nieco przekroczysz limit.


Bardziej wydajne mieszanie / dopasowywanie poleceń pochodzi z użycia pierścienia zabijania, który działa tak samo jak w Emacsie. ctrl-y, aby wkleić ostatnie ctrl-w / ctrl-u / ctrl-backspace / alt-d. Alt-y, aby przewijać starszy zabity tekst.

Wiele kombinacji klawiszy Ctrl-W lub cokolwiek z rzędu robi się przy wejściu Kill-Ring. Użyj lewej i prawej strzałki lub czegoś, aby rozbić wpis, jeśli chcesz usunąć dwie rzeczy i wkleić tylko jedną później.

Łącząc je wszystkie razem, możesz

  • zacznij pisać polecenie
  • ctrl-r, aby wrócić do starego polecenia i przejąć jego część za pomocą klawiszy control-w lub podobnych.
  • esc-r lub alt+rprzywrócić go do stanu sprzed usunięcia części.
  • alt - >aby przejść do końca historii (tj. strzałka w dół do końca), aby wrócić do polecenia, w którym się znajdowałeś.

Inne wskazówki dotyczące interaktywnego użytkowania:

Włącz shopt -s globstar, abyś mógł to zrobić **/*.c(rekurencyjne, w tym bieżący katalog). Czasami przydatny do użytku interaktywnego, ale zwykle find -name '*.c' -exec foo {} +jest lepszy.

Jeśli piszesz skrypty bash, przydaje się również shopt -s extglobwłączenie ich w interaktywnych powłokach. Będziesz czasami znaleźć zastosowanie do rzeczy, jak *.!(c|h)dopasować pliki, które nie kończą się .c lub .h.

Znajdź dla aliasów chcesz ls -l, lessi coś jeszcze dużo zrobić. ( cp -i, mv -ii rm -Isą ładne. Nie przyzwyczajaj się do polegania na nich, aby robić selektywne rm. GNU rm's-pytam raz o wszystkie argumenty.)

Lubię alias m=less(m dla „więcej”). Mam lessskonfigurować z ,i .zobowiązany do poprzedniego / następnego pliku ( lesskey). Domyślnie jest to sekwencja wielokrotnego naciskania, której nie można używać z autorepeat.


Lubię robić wszystko na ekranie GNU. Śledzenie numerowanych okien ekranowych jest dla mnie łatwiejsze niż mnóstwo kart w Konsole (lub innym emulatorze terminala, którego próbowałem). Jeśli jeszcze tego nie wiesz screen, naucz się tmux, ponieważ jest nowszy i mniej kruchy.

Aby uzyskać coś takiego jak funkcjonalność otwierania nowej powłoki z tym samym cwd co inna powłoka, używam niestandardowego haka dla cd / pushd / popd, który pozwala mi cds 8na cd do dowolnego katalogu, którego używa moja powłoka w oknie ekranowym 8. Działa to nawet w przypadku powłok poza sesją ekranową, o ile istnieje tylko jedna sesja ekranowa.

Peter Cordes
źródło
Mój nie wydaje się być „odpowiednio skonfigurowany”. Wiele skrótów, które tu widzę, nie działa, używam standardowego terminalu z Ubuntu 14.04. Jak mogę to skonfigurować?
JorgeeFG
@JorgeeFG: Myślę, że działało to dla mnie od razu po uruchomieniu gnome-terminalw Ubuntu 14.04, zanim przełączyłem się na KDE. Odpowiednia opcja znajduje się w ustawieniach terminala, prefiksie esc vs high-bit, a może w niektórych innych ustawieniach. Niektóre z nich nie działają idealnie dla mnie przez ssh. (np. ctrl w lewo / prawo munge kod ucieczki dla klawisza strzałki, i 5Dpojawia się dosłownie)
Peter Cordes
7

Dodaj następujące wiersze do swojego ~/.inputrc

"\e[A": history-search-backward
"\e[B": history-search-forward

Jest to podobne do odpowiedzi egmonta, ale zamiast używać Page Up i Page Down, wykorzystuje sekwencje specjalne dla Arrow Up i Arrow Down. Ten sposób jest znacznie wygodniejszy w użyciu na komputerze Mac.

John Slavick
źródło
4

Zawsze mam tendencję do konfigurowania moich maszyn z dużą wartością HISTSIZE, więc utrzymuje dłuższą listę historii, a także HISTTIMEFORMAT z wartością znacznika czasu, dzięki czemu mogę zobaczyć, kiedy polecenie zostało uruchomione.

export HISTSIZE=10000
export HISTTIMEFORMAT="%m/%d/%Y %T "
Alpha01
źródło
3

Zazwyczaj używam środków, aby połączyć historypolecenie zgrep

TO ZNACZY:

history | grep <command im looking for>

To wyświetli ponumerowaną historię poleceń, które wpisałeś, które zawierają to polecenie, możesz następnie użyć:

!<number listed in history command>

aby powtórzyć to polecenie.

TO ZNACZY:

history | grep history

142  history
143  history | grep lvresize
568  history | grep echo
570  history | grep echo
571  history | grep history

śledzony przez: !571

powtórzy się history | grep history

Sos
źródło
1
CR = znacznie lepiej + znacznie bezpieczniej
PSkocik,
1
Być może osobiście uważam, że historia potoczyła się po grep, aby być szybszym sposobem na znalezienie większości poleceń. Jeśli chodzi o bezpieczniejsze, nie jestem pewien, co masz na myśli, jakie są nieodłączne zagrożenia związane z używaniem historii w kontekście jej przeszukiwania za pomocą cR?
Sos
2
@Gravy Podejrzewam, że PSkocik oznacza, że !podstawienie historii jest mniej bezpieczne.
derobert
3
@Gravy Nieodłącznym ryzykiem byłoby przypadkowe wprowadzenie niewłaściwej linii. Nie mam pojęcia, dlaczego twój terminal się zawiesił, chyba że użyłeś Control-S i masz włączoną kontrolę przepływu xon / xoff (często domyślną). Jeśli tak, Control-Q przywróci go.
derobert
1
Zgadzam się z @PSkocik, cr jest znacznie lepszy, ponieważ łatwiej jest edytować linię historii, niż po prostu uruchomić ją ponownie w ten sam sposób. Ponowne uruchomienie dokładnie tej samej komendy jest trywialnym przypadkiem tego, co możesz zrobić, aby zaoszczędzić czas na ponownym wpisywaniu odmian na skomplikowanych jedno-liniowych liniach lub wypełnianiu innego pliku długą ścieżką. Zobacz moją odpowiedź.
Peter Cordes,
1

Codziennie korzystałem z 4 porad (i kilku innych) w moim terminalu bash:

  • Wykonaj ostatnie polecenie: !!

  • Wykonaj polecenie N z historii: !N

  • Wydrukuj ostatnie polecenie zaczynające się od prefiksu z historii: !prefix:p

  • Wykonaj ostatnie polecenie, zaczynając od prefiksu z historii: !prefix

Nolwennig
źródło
1

Jeśli możesz użyć zshzamiast bashsiebie stożka, użyj do tego oh-my-zsh .

Zawiera strzałkę w górę nawigacji w historii poleceń. Pozwala również na tę samą nawigację, gdy już wpisałeś tekst (jak Mathlab).

edycja: Zawiera także inne rzeczy przeznaczone dla programistów, takie jak aliasy i motywy. Te dodatki sprawiają, że dystrybucja jest większa i bardziej złożona w użyciu.

https://github.com/robbyrussell/oh-my-zsh

użytkownik9869932
źródło
1
oh-my-zshzawiera mnóstwo rzeczy. Równie dobrze możesz powiedzieć: ta dokładna funkcja jest zawarta w tej dystrybucji, gdy wszystko, czego potrzebujesz, to określone ustawienie lub aplikacja.
muru
Zredagowałem post: ostrzegałem, że jest większy niż prosta aplikacja.
user9869932
1

Dodaj następujący alias do ~ / .bashrc

alias h='history | awk '"'"'{$1="";print}'"'"' |sed "s/^ *//" |grep -v "^h " | sort | uniq | grep'

Użycie: h fireotrzymam listę poleceń zawierających ogień . lub h ^firedostanę listę poleceń zaczynających się od ognia .

Jest to przydatne, gdy chcę wyświetlić serię poleceń jednocześnie.

Nawiasem mówiąc, '"'"'jest brzydka, ale nie mogłem znaleźć innych sposobów na uniknięcie pojedynczych cudzysłowów w pojedynczych cudzysłowach.

Hosi Golden
źródło
fyi - h="history | awk '{\$1=\"\"; print}'powinno działać. alternatywnie utwórz funkcję i wywołaj ją.
DarkHeart,
dziękuję DarkHeart, ale wypróbowałem twój kod, okazało się, że nie działa w moim środowisku, może jest coś innego w moim
Hosi Golden