Bash-Befehl zum Kopieren vor dem Cursor und Einfügen nach dem?

24

Ich bin mir nicht sicher, wie ich das ausdrücken soll, aber ich finde mich oft dabei, Befehle wie diesen einzugeben:

cp /etc/prog/dir1/myconfig.yml /etc/prog/dir1/myconfig.yml.bak

Normalerweise schreibe ich den Pfad nur zweimal aus (mit Tabulatorvervollständigung), oder ich kopiere den Pfad und füge ihn mit dem Cursor ein. Gibt es einen Bashfoo, der das Tippen erleichtert?

user1028270
quelle
2
Ich denke du meinst bash-fu:)
Katze

Antworten:

43

Es gibt eine Reihe von Tricks (ich glaube, es gibt ein Duplikat), aber dazu tendiere ich

cp /etc/prog/dir1/myconfig.yml{,.bak}

was zu Ihrem Befehl erweitert wird.

Dies wird als Klammererweiterung bezeichnet . In der hier verwendeten Form gibt der {}Ausdruck eine Anzahl von durch Kommas getrennten Zeichenfolgen an. Diese "erweitern" den gesamten /etc/prog/dir1/myconfig.yml{,.bak}Ausdruck und ersetzen den {}Teil durch jede Zeichenkette: die leere Zeichenkette, geben /etc/prog/dir1/myconfig.ymlund dann .bakgeben /etc/prog/dir1/myconfig.yml.bak. Das Ergebnis ist

cp /etc/prog/dir1/myconfig.yml /etc/prog/dir1/myconfig.yml.bak

Diese Ausdrücke können verschachtelt werden:

echo a{b,c,d{e,f,g}}

produziert

ab ac ade adf adg

Es gibt eine Variante, bei der Zahlen verwendet werden, um Sequenzen zu erzeugen:

echo {1..10}

produziert

1 2 3 4 5 6 7 8 9 10

und Sie können auch den Schritt angeben:

echo {0..10..5}

produziert

0 5 10
Stephen Kitt
quelle
Verdammt, das ist süß. Ich dachte, ich wäre nicht der erste, der etwas fragt, nur eine knifflige Frage.
user1028270
Was macht das Komma dort?
user1028270
5
Siehe Klammererweiterung im Handbuch: Hier werden die in der Erweiterung verwendeten Werte getrennt. Hier sind die beiden Werte der leere String und .bak.
Stephen Kitt
12

Die Verlaufserweiterung kann für solche Aufgaben hilfreich sein (vorausgesetzt, der Bash-Verlauf ist aktiviert).

In Ihrem Beispiel könnten Sie Folgendes tun:

cp /etc/prog/dir1/myconfig.yml !#:1.bak

Hier !#bezieht sich das auf die aktuelle Zeile, !#:1auf Parameter 1 in der aktuellen Zeile
und!#:1.bak auf Parameter 1 in der aktuellen Zeile, wobei '.bak' am Ende angeheftet ist.

Wenn Sie den Verlaufsspezifizierer eingegeben haben, können Sie ihn mit Ctrl+ Alt+ Eauf seinen tatsächlichen Wert erweitern, wenn Sie z. B. den Dateinamen überprüfen oder ändern möchten.

Der Abschnitt "History Expansion" in den Bash-Manpages enthält weitere Informationen.

Kacken
quelle
8

Ähnlich wie die Antwort von Progo, aber etwas einfacher: C-wSchneidet das Wort links vom Cursor ab ("tötet") und C-yfügt es erneut ein ("reißt").

$ cp /etc/dir1/myconfig.yml                              (C-w)
$ cp                                                     (C-y)
$ cp /etc/dir1/myconfig.yml                              (space, C-y)
$ cp /etc/dir1/myconfig.yml /etc/dir1/myconfig.yml       (finish text)
$ cp /etc/dir1/myconfig.yml /etc/dir1/myconfig.yml.bak
Mindriot
quelle
2
Beachten Sie auch, dass Sie dies mit mehreren Wörtern in einer Reihe tun können (wenn Ihr Dateiname beispielsweise Leerzeichen enthält) und Cy alle einfügt, solange Sie den Cursor nicht bewegt oder etwas anderes dazwischen eingegeben haben. Jede Mischung von Löschbefehlen mit Ausnahme von Einzelzeichen-Löschbefehlen (z. B. Rücktaste / Entf / Strg-D) funktioniert damit.
Random832
6

Sie können auch von der Kommandozeile aus Ausschneiden und Einfügen (Kill-Yank in Emacs / Bash-Begriffen), um Teile zur Bearbeitung zu duplizieren.

M-dtötet vorwärts bis zur Wortgrenze, und Sie können Text mehrmals töten, und alle werden zum Ziehen zu einer einzigen „Paste“ zusammengefügt. Praktisch!

Ziehen Sie dies alles zurück zur Befehlszeile am Cursor durch C-y. Wenn Sie also eine Zeile wie diese haben (das Blockelement █ zeigt die Cursorposition an):

$ cp avb.txt                 (M-b M-b)
$ cpavb.txt                  (M-d) kill the word 'avb'
$ cp █.txt                    (C-y) yank it back
$ cp avb█.txt                 (C-e) to the end of line
$ cp avb.txt                 (C-y) yank it again
$ cp avb.txt avb             finish the line
$ cp avb.txt avb.foo

In beiden Fällen ist es von Vorteil, sich mit den Angeboten von bash in der interaktiven Schlüsselabteilung vertraut zu machen. http://web.mit.edu/gnu/doc/html/features_7.html

unperson325680
quelle
6

In tcshoder zsh, Alt+Ctrl+_in emacsBetrieb (copy-prev-word Widget) fügt das letzte Wort, so

cp sehr langer Pfad Alt+Ctrl+_.back

bashhat ein copy-backward-wordWidget (standardmäßig nicht an eine Taste gebunden), das jedoch nur das Wort in den Ringpuffer kopiert. Sie müssen auch Ctrl-Y(im emacsModus) drücken, um es zu ziehen. Aber du könntest tun:

bind '"\e[cpw~": copy-backward-word'
bind '"\e\C-_": "\e[cpw~\C-Y"'

Um Alt+Ctrl+_das Kopieren / Snarf und Einfügen / Yank wie in tcsh/ zu tun zsh.

Stéphane Chazelas
quelle