Come cambiare rapidamente la prima parola in un comando Bash?


44

Vorrei migliorare un po 'il mio flusso di lavoro con Bash, e mi rendo conto che spesso voglio eseguire lo stesso comando su un altro eseguibile.

Qualche esempio:

Git (dove vorrei cambiare rapidamente la seconda parola):

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

Cat / rm (dove deve essere cambiata solo la prima parola):

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

So che posso colpire Ctrl+ apoi Delper rimuovere la prima parola, ma mi chiedo se c'è un modo più veloce per farlo.



Onestamente, penso che sia più sicuro usare Ctrl + a ed eliminare. Non è sicuramente molto lento.
agweber

Risposte:


56

!$ si espande fino all'ultima parola del comando precedente.

Quindi potresti fare:

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

rm !$

o:

git diff foo/bar.c

git checkout !$

I tuoi esempi sono successi solo per ripetere l'ultima parola, quindi ha !$funzionato bene. Se in realtà avevi molti argomenti che volevi ripetere e volevi solo cambiare la prima parola, potresti usare !*, che si espande a tutte le parole del comando precedente tranne lo zeroth.

Vedi la sezione "ESPANSIONE STORIA" della bashpagina man. C'è molta flessibilità lì.


16
Giusto e corretto. Vorrei solo mettere un avvertimento : con !$te non hai il pieno controllo visivo della linea che stai correndo . Questo può risultare dannoso a volte. Soprattutto se si verifica un errore di stampa. Prende dal historycosa espandere. Quindi se si scrive l'ultimo comando con uno spazio all'inizio, probabilmente questo comando non finirà nella cronologia. Quando eseguirai il tuo nuovo comando con !$la shell non prenderai i parametri dall'ultima riga di comando digitata ma solo dall'ultima della cronologia. Qui stesse parole in più.
Hastur,

1
@Hastur È possibile impostare la shell per espandere la cronologia nella scheda o su Invio per prevenire incidenti.
slhck,

2
@Hastur ecco perché devi premere due volte intro in zsh (promozione spudorata)
Braiam

@Hastur - Quando ho qualche dubbio su cosa accadrà o tardivamente mi rendo conto che devo fare qualcos'altro prima di eseguire qualcosa di lungo che ho appena digitato, vado all'inizio della riga e aggiungo un #o un echo così posso vederlo ed entra nella storia, così posso riaverlo indietro ed eseguirlo di nuovo senza il prefisso disabilitante.
Joe,

28

Ctrl+ aper andare all'inizio della riga, quindi Alt+ dper eliminare la prima parola.


9
La scorciatoia per l'eliminazione è in realtà Meta + d, e Meta è solitamente mappata su Alt su macchine Linux. Su piattaforme in cui non è così, un'alternativa per ottenere il modificatore Meta è usare Escape come prefisso. Vedi en.wikipedia.org/wiki/Meta_key
Gustavo Giráldez il

2
@ GustavoGiráldez se vuoi approfondire, Meta+Dè valido solo se emacsè abilitato (tramite set -o emacso semplicemente per impostazione predefinita). Non funzionerà in modalità editor inferiore o se emacsè disabilitato.
TC1

In molti terminali (poiché questa è una cosa terminale e non una cosa Bash), anche la chiave home andrà all'inizio di una riga. Molti laptop mappano Fn + Sinistra sul tasto Home. Allo stesso modo, la chiave di fine andrà generalmente alla fine della riga. Devo ancora usare un emulatore di terminale che non supporta questi tasti di scelta rapida.
Kat,

1
@Mike D'altra parte, C-ae M-dsono molto più veloci da digitare se le tue mani sono già in posizione di battitura.
Jjlin,

@Mike Questa è una cosa bash. Digita cate confronta ciò che ottieni quando premi Home ( ^[[Hqui) e quando premi Ctrl + a ( ^A).
Jonas Schäfer,

17

Non sono sicuro che sarebbe effettivamente più veloce o meno, ma vedi questo articolo, in particolare il punto # .3:

  1. Sostituisci una stringa dal comando precedente usando ^ str1 ^ str2 ^

Nel seguente esempio, per prima cosa abbiamo eseguito il comando ls per verificare un file. Successivamente ci siamo resi conto che vogliamo visualizzare il contenuto del file. Invece di digitare nuovamente l'intero nome del file, possiamo semplicemente sostituire "ls" nel comando precedente con "cat" come mostrato di seguito.

$ ls /etc/cron.daily/logrotate

$ ^ls^cat^
cat /etc/cron.daily/logrotate

15

Alt+.

Se hai solo bisogno di ripetere l'ultima parte di uno dei comandi precedenti puoi usare Alt+ .che incollerà l'ultimo argomento preso dall'ultima riga della cronologia.

Se premuto più di una volta sostituirà quello appena incollato con l'ultimo argomento della riga prima ...

Ad esempio se gli ultimi 2 comandi fossero:

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

Nella shell scrivo rme premo Alt+ .apparirà:

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

se premo di nuovo Alt+ .apparirà invece

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

e così via...


Non so perché ma questo non funziona sulla mia console Mac.
Lulalala,

Qui ci sono le scorciatoie da tastiera con cui è noto lavorare bash. A proposito, sei sicuro di usare bash come shell ?
Hastur,

1
Immagino sia una cosa Mac. Quando
scrivo


12

Oltre alla risposta di @jjlin, potresti essere interessato dai seguenti suggerimenti:

  • Ctrl+ wcancella la parola alla tua sinistra
  • Ctrl+ kcancella dal cursore alla fine della riga di comando
  • Ctrl+ ucancella dal cursore all'inizio della riga di comando
  • Alt+ bsposta il cursore di una parola all'indietro
  • Alt+ fsposta il cursore di una parola in avanti
  • $_ contiene l'ultimo argomento della precedente riga di comando

Per ulteriori informazioni, consultare la sezione "Nomi dei comandi Readline" della bashpagina man.

per esempio:

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

Questi sono buoni consigli, ma non rispondono alla domanda.
Slhck,

@slhck IMHO lo fa perché il titolo della domanda non corrisponde agli esempi forniti. Se ci concentriamo sugli esempi, come ho fatto io, il titolo dovrebbe essere "Come cambiare rapidamente una parola in un comando bash?" . Questo è anche il motivo per cui la mia risposta è "oltre a quella di @jjlin". Ma credo che la domanda debba essere chiarita.
maiki,

L'OP vuole sempre rimuovere (scambiare) le prime nparole nel comando, con n = 1nel primo esempio e n = 2nel secondo. La risposta di jjlin mostra come eliminare la prima parola (e riapplicando il collegamento, elimina fino a nparole). La tua risposta elenca alcune scorciatoie di Bash (che sono davvero utili), ma nessuna di esse è un modo efficace per eliminare le prime nparole.
Slhck,

Hm, rileggendo, il $_parametro probabilmente funzionerebbe se ci fosse solo un argomento (cioè se n = m - 1dov'è mil numero totale di argomenti). Il resto delle scorciatoie è tuttavia irrilevante per la domanda.
Slhck,

@slhck Per motivi di discussione ho letto il primo esempio come "sostituisci la seconda parola" :-)
maiki

8

Se sei esperto in vi, puoi attivare le associazioni vi in ​​bash (la maggior parte delle shell?) Usando il comando set -o vi. Quindi, è possibile utilizzare i normali tasti vi per modificare il comando. Nel tuo primo esempio, potresti fare ^wcwper eliminare "diff", quindi cambiarlo in checkout.

Potrebbe non valere la pena apprendere le combinazioni di tasti vi solo per modificare la riga di comando, ma se le conosci già è un buon aumento della produttività.


Ho imparato su kornshell, così è set -o vistato come ho vissuto! Lo faccio anche nei miei suggerimenti bash.
bgStack15,

bindkey -vper zsh. Esc 0 c w
user530873,

6

Ci sono molti modi per scuoiare questo gatto!

Per sostituire una stringa specifica, ^old^new^extraprenderai il tuo comando precedente, sostituisci oldcon newe aggiungi extra. Potresti fermarti appena vuoi; ad esempio ^oldsostituirà oldcon la stringa vuota e aggiungerà la stringa vuota (essenzialmente eliminando olde non facendo più nulla).

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

Variante particolarmente utile di questo:

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

Per sostituire una parola specifica, è possibile utilizzare !m:n-pper fare riferimento alle parole ntramite pil comando m(utilizzare i numeri negativi per contare indietro dal comando corrente). È possibile omettere la -pparte per fare riferimento a una sola parola e omettere la :m-pparte per fare riferimento a un intero comando. I moduli speciali !!per !-1, !$per l'ultima parola del comando precedente e !*per gli argomenti (tutti tranne la parola 0) del comando precedente sono piuttosto utili.

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

Uso spesso entrambi; zsh è particolarmente bello qui, poiché colpire tab espande le cose criptiche per assicurarti di averlo bene.

Ci sono anche molti modi per farlo con l'editing di linea. Leggi le combinazioni di tasti della tua shell.


-2

La maggior parte dei programmi terminali supporta ...

  • Premere <Up-Arrow>secondo necessità per visualizzare nuovamente una delle precedenti righe di comando dalla cronologia.
    • Premere <Down-Arrow>se necessario per andare avanti nell'elenco cronologico.
  • Premere <Left-Arrow>secondo necessità per spostare il cursore alla fine della seconda parola.
  • Premere <Backspace>secondo necessità per cancellare la seconda parola.
  • Digita la seconda parola sostitutiva.
    • Premere <Right-Arrow>/ <Left-Arrow>se necessario per riposizionare per ulteriori modifiche.
  • Premi <RETURN>per eseguire il comando

Se la riga di comando desiderata non era recente, fai una ricerca inversa con <Ctrl-r>come descritto nella domanda ...
C'è un modo di usare ctrl-r dopo aver digitato parte del comando in bash?
Quindi modificare tramite i tasti freccia in base alle esigenze.


-3

Cosa faccio (Ubuntu / bash):

1) Arrow upehi per tornare al comando precedente
2) Hometasto per tornare all'inizio
3) Modificare il comando secondo necessità.

A prova di idiota e particolarmente utile per i comandi multilinea.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.