Wie ändere ich schnell das erste Wort in einem Bash-Befehl?

44

Ich möchte meinen Workflow mit Bash ein wenig verbessern und stelle fest, dass ich häufig den gleichen Befehl für eine andere ausführbare Datei ausführen möchte.

Einige Beispiele:

Git (wo ich das zweite Wort schnell ändern möchte):

git diff     foo/bar.c
git checkout foo/bar.c

Cat / rm (wobei nur das erste Wort geändert werden muss):

cat foo/is/a/very/long/path/to/bar.c
rm  foo/is/a/very/long/path/to/bar.c

Ich weiß, dass ich Ctrl+ adann Deldrücken kann , um das erste Wort zu entfernen, aber ich frage mich, ob es einen schnelleren Weg gibt, dies zu tun.

nowox
quelle
Ehrlich gesagt denke ich, dass es am sichersten ist, einfach Strg + a zu verwenden und zu löschen. Es ist definitiv nicht sehr langsam.
22.

Antworten:

56

!$ wird bis zum letzten Wort Ihres vorherigen Befehls erweitert.

Sie könnten also Folgendes tun:

cat foo/is/a/very/long/path/to/bar.c

rm !$

oder:

git diff foo/bar.c

git checkout !$

Ihre Beispiele haben zufällig nur das letzte Wort wiederholt, also hat es gut !$funktioniert. Wenn Sie tatsächlich viele Argumente hatten, die Sie wiederholen wollten, und Sie nur das erste Wort ändern wollten, könnten Sie verwenden !*, das auf alle Wörter des vorherigen Befehls mit Ausnahme der Null erweitert wird.

Siehe den Abschnitt "HISTORY EXPANSION" auf der bashManpage. Da gibt es viel Flexibilität.

Spiff
quelle
16
Richtig und richtig. Ich möchte nur eine Warnung ausdrücken : Mit !$Ihnen haben Sie keine volle visuelle Kontrolle über die Linie, die Sie gerade laufen . Dies kann manchmal schädlich sein. Insbesondere, wenn Sie einen Druckfehler haben. Es geht historydarum, was zu erweitern. Wenn Sie also den letzten Befehl mit einem Leerzeichen am Anfang schreiben, wird dieser Befehl wahrscheinlich nicht im Verlauf enden. Wenn Sie Ihren neuen Befehl mit !$der Shell ausführen , werden die Parameter nicht von der zuletzt eingegebenen Befehlszeile übernommen, sondern nur vom letzten des Verlaufs. Hier gleich mehr Worte.
Hastur
1
@Hastur Sie können Ihre Shell so einstellen, dass der Verlauf auf der Registerkarte oder bei der Eingabe erweitert wird, um Unfälle zu vermeiden.
Slhck
2
@Hastur das ist, warum Sie Intro zweimal in zsh (schamlose Förderung)
drücken müssen
@Hastur - Wenn ich Zweifel daran habe, was passieren wird, oder mir verspätet klar wird, dass ich erst etwas anderes tun muss, bevor ich etwas ausführe, das ich gerade eingetippt habe, gehe ich an den Anfang der Zeile und füge ein #oder ein hinzu, echo damit ich kann Sieh es dir an und es geht in die Geschichte ein, damit ich es sofort wieder verwenden und erneut ausführen kann, ohne das Präfix zu deaktivieren.
Joe
28

Ctrl+ aum an den Zeilenanfang zu springen , Alt+ dum das erste Wort zu löschen.

jjlin
quelle
9
Die Verknüpfung zum Löschen von Wörtern lautet tatsächlich Meta + d, und Meta wird auf Linux-Computern normalerweise Alt zugeordnet. Auf Plattformen, auf denen dies nicht der Fall ist, besteht eine Alternative zum Abrufen des Meta-Modifikators darin, das Escape als Präfix zu verwenden. Siehe en.wikipedia.org/wiki/Meta_key
Gustavo Giráldez
2
@ GustavoGiráldez Wenn Sie tief gehen möchten, dann Meta+Dist nur gültig, wenn emacsaktiviert ist (über set -o emacsoder einfach standardmäßig). Es funktioniert nicht im minderwertigen Editor- Modus oder wenn emacsdeaktiviert.
TC1
In vielen Terminals (da dies eine Terminalsache und keine Bash-Sache ist) geht die Home-Taste auch an den Anfang einer Zeile. Viele Laptops ordnen Fn + Links zur Home-Taste zu. Ebenso wird die Ende-Taste normalerweise an das Ende der Zeile gehen. Ich habe noch keinen Terminal-Emulator verwendet, der diese Hotkeys nicht unterstützt.
Kat
1
@Mike Auf der anderen Seite C-aund M-dsind viel schneller zu tippen, wenn sich Ihre Hände bereits in Schreibposition befinden.
JJLIN
@ Mike Das ist eine heftige Sache. Geben Sie ein catund vergleichen Sie, was Sie erhalten, wenn Sie Home ( ^[[Hhier) und Strg + a ( ^A) drücken .
Jonas Schäfer
17

Ich bin nicht sicher, ob es tatsächlich schneller wäre oder nicht, aber siehe diesen Artikel, insbesondere Punkt # .3:

  1. Ersetzen Sie eine Zeichenfolge aus dem vorherigen Befehl mit ^ str1 ^ str2 ^

Im folgenden Beispiel haben wir zuerst den Befehl ls ausgeführt, um eine Datei zu überprüfen. Später wurde uns klar, dass wir den Inhalt der Datei anzeigen möchten. Anstatt den gesamten Dateinamen erneut einzugeben, können Sie das "ls" im vorherigen Befehl wie unten gezeigt durch "cat" ersetzen.

$ ls /etc/cron.daily/logrotate

$ ^ls^cat^
cat /etc/cron.daily/logrotate
Benguin
quelle
15

Alt+.

Wenn Sie nur den letzten Teil eines der vorherigen Befehle wiederholen müssen, können Sie Alt+ verwenden ., um das letzte Argument aus der letzten Zeile des Verlaufs einzufügen.

Wenn mehr als einmal gedrückt wird, wird das, was gerade eingefügt wurde, durch das letzte Argument der Zeile vor ... ersetzt.

ZB wenn die letzten 2 Befehle wären:

cat foo/is/a/very/long/path/to/bar.c
pico foo/is/a/very/long/path/to/SomeWhereElse.c

In der Shell ich schreibe rmund ich drücken Alt+ .es erscheint:

rm foo/is/a/very/long/path/to/SomeWhereElse.c

Wenn ich erneut drücke , wird stattdessen Alt+ .angezeigt

rm foo/is/a/very/long/path/to/bar.c

und so weiter...

Hastur
quelle
Ich weiß nicht warum, aber das funktioniert auf meiner Mac-Konsole nicht.
Lulalala
Hier gibt es die Tastaturkürzel , mit denen bekanntermaßen gearbeitet wird bash. BTW Sind Sie sicher, dass Sie Bash als Shell verwenden ?
Hastur
1
Ich denke, das ist eine Mac-Sache. Wenn ich
tippe
12

Zusätzlich zur Antwort von @jjlin könnten Sie die folgenden Tipps interessieren:

  • Ctrl+ wlöscht das Wort links von dir
  • Ctrl+ klöscht vom Cursor bis zum Ende der Befehlszeile
  • Ctrl+ ulöscht vom Cursor zum Anfang der Befehlszeile
  • Alt+ bbewegt den Cursor ein Wort zurück
  • Alt+ fbewegt den Cursor ein Wort vorwärts
  • $_ Enthält das letzte Argument der vorherigen Befehlszeile

Weitere Informationen hierzu finden Sie im Abschnitt "Readline Command Names" der bashManpage.

z.B:

cat foo/is/a/very/long/path/to/bar.c
rm $_
maiki
quelle
Das sind nette Tipps, aber sie beantworten die Frage nicht.
Slhck
@slhck IMHO, weil der Fragentitel nicht mit den angegebenen Beispielen übereinstimmt. Wenn wir uns wie ich auf die Beispiele konzentrieren, sollte der Titel "Wie kann man ein Wort in einem Bash-Befehl schnell ändern?" Lauten. . Dies ist auch der Grund, warum meine Antwort "zusätzlich zu der von @jjlin" lautet. Aber ich denke, die Frage sollte geklärt werden.
Maiki
Das OP möchte immer die ersten nWörter im Befehl entfernen (austauschen) , n = 1im ersten Beispiel und n = 2im zweiten. Die Antwort von jjlin zeigt, wie Sie das erste Wort löschen (und durch erneutes Anwenden der Verknüpfung bis zu nWörter löschen ). In Ihrer Antwort sind einige Bash-Verknüpfungen aufgeführt (die in der Tat nützlich sind), aber keine davon ist eine effiziente Methode zum Löschen der ersten nWörter.
Slhck
Hm, nochmal lesen, der $_Parameter würde wahrscheinlich funktionieren, wenn es nur ein Argument gibt (dh wenn n = m - 1wo mdie Gesamtzahl der Argumente ist). Der Rest der Verknüpfungen ist jedoch für die Frage irrelevant.
Slhck
@slhck Um zu argumentieren, habe ich das erste Beispiel als "das 2. Wort ersetzen" gelesen :-)
maiki
8

Wenn Sie sich mit vi auskennen, können Sie vi-Bindungen in bash (die meisten Shells?) Mit dem Befehl aktivieren set -o vi. Anschließend können Sie Ihren Befehl mit den normalen vi-Tasten bearbeiten. In Ihrem ersten Beispiel können Sie ^wcw"diff" löschen und dann in "checkout" ändern.

Es lohnt sich vielleicht nicht, die vi-Tastenkombinationen nur zum Bearbeiten der Befehlszeile zu erlernen, aber wenn Sie sie bereits kennen, ist sie eine ordentliche Produktivitätssteigerung.

Chaosed0
quelle
Ich habe auf den Punkt gebracht, so habe set -o viich gelebt! Ich mache das sogar in meinen Bash-Anweisungen.
bgStack15
bindkey -vfür zsh. Esc 0 c w
user530873
6

Es gibt viele Möglichkeiten, diese Katze zu häuten!

Um eine bestimmte Zeichenfolge zu ersetzen, ^old^new^extraübernehmen Sie Ihren vorherigen Befehl, ersetzen Sie oldmit newund hängen Sie ihn an extra. Sie können so früh aufhören, wie Sie möchten; zB ^oldwird durch olddie leere Zeichenkette ersetzt und die leere Zeichenkette angehängt (im Wesentlichen löschen oldund nichts mehr tun).

1. ^diff^checkout
2. ^cat^rm

Besonders nützliche Variante davon:

for i in `seq 1 10`; do echo something complicated; done
# inspect the output to see if it looks right
^echo

Um ein bestimmtes Wort zu ersetzen, können Sie !m:n-pauf Wörter ndurch pden Befehl verweisen m(verwenden Sie negative Zahlen, um vom aktuellen Befehl zurück zu zählen). Sie können den -pTeil weglassen , um auf ein einzelnes Wort zu verweisen, und den :m-pTeil weglassen , um auf einen gesamten Befehl zu verweisen. Sonderformen !!für !-1, !$für das letzte Wort des vorherigen Befehls und !*für die Argumente (außer Wort 0) des vorherigen Befehls sind sehr praktisch.

1. !!:0 checkout !!:2-
2. rm !*

Ich benutze oft beide; zsh ist hier besonders schön, da das Drücken der Tabulatortaste das kryptische Material erweitert, um sicherzustellen, dass Sie es richtig verstanden haben.

Es gibt auch so viele Möglichkeiten, dies mit der Zeilenbearbeitung zu tun. Lesen Sie die Tastenkombinationen Ihrer Shell.

Daniel Wagner
quelle
-2

Die meisten Terminalprogramme unterstützen ...

  • Drücken Sie <Up-Arrow>nach Bedarf, um eine der vorherigen Befehlszeilen aus dem Verlauf erneut anzuzeigen.
    • Drücken Sie <Down-Arrow>nach Bedarf, um die Verlaufsliste vorwärts zu durchlaufen.
  • Nach <Left-Arrow>Bedarf drücken, um den Cursor an das Ende des zweiten Wortes zu bewegen.
  • Drücken Sie <Backspace>nach Bedarf, um das zweite Wort zu löschen.
  • Geben Sie das zweite Ersatzwort ein.
    • Drücken Sie bei Bedarf <Right-Arrow>/ <Left-Arrow>, um die Position zu ändern.
  • Drücken Sie <RETURN>, um den Befehl auszuführen

Wenn die gewünschte Befehlszeile nicht aktuell war, führen Sie eine Reverse-i-Suche <Ctrl-r>wie in Frage beschrieben durch.
Gibt es eine Möglichkeit, Strg-R zu verwenden, nachdem Sie einen Teil des Befehls in Bash eingegeben haben?
Dann über die Pfeiltasten nach Bedarf bearbeiten.

DocSalvager
quelle
-3

Was ich mache (Ubuntu / bash):

1) Arrow upHey, um zum vorherigen Befehl zurückzukehren.
2) HomeTaste, um zum Anfang zurückzukehren.
3) Ändern Sie den Befehl nach Bedarf.

Idiotensicher und besonders nützlich für mehrzeilige Befehle.

Vorac
quelle