Bagaimana cara menggunakan argumen dari perintah sebelumnya?


287

Saya tahu bahwa Esc+ .memberi Anda argumen terakhir dari perintah terakhir.

Tapi saya tertarik pada argumen pertama dari perintah terakhir. Apakah ada kunci yang mengikat untuk melakukannya?

Pada baris yang sama, apakah ada cara umum untuk mendapatkan argumen ke-n dari perintah terakhir? Saya tahu bahwa dalam skrip bash, Anda dapat menggunakan $0, $1dll., Tetapi ini tidak berfungsi pada commandline.

Juga, bagaimana dengan mengulangi argumen 0 dari perintah sebelumnya, seperti yang dapat kita lakukan dengan argumen terakhir dengan terus menekan Esc+ .?

Jawaban:


284

Sama seperti M-.(meta-dot atau esc-dot atau alt-dot) adalah fungsi readline yank-last-arg, M-C-y(meta-control-y atau esc-ctrl-y atau ctrl-alt-y) adalah fungsi readline yank-nth-arg. Tanpa menentukan n, itu menarik argumen pertama dari perintah sebelumnya.

Untuk menentukan argumen, tekan Escape dan nomor atau tahan Alt dan tekan nomor. Anda dapat melakukan Alt- -untuk mulai menentukan angka negatif kemudian lepaskan Alt dan tekan digit (ini akan dihitung dari akhir daftar argumen.

Contoh:

Masukkan perintah berikut

$ echo a b c d e f g
a b c d e f g

Sekarang pada prompt berikutnya, ketik echo(dengan spasi berikut), lalu

Tekan Alt- Ctrl- ydan sekarang Anda akan melihat:

$ echo a

tanpa menekan Enterlagi, lakukan hal berikut

Tekan Alt- 3 Alt- Ctrl-y

Tekan Alt- - 2 Alt- Ctrl-y

Sekarang Anda akan melihat:

$ echo ace

Ngomong-ngomong, Anda bisa meletakkannya echodi jalur dengan memilih argumen 0:

Tekan Alt- 0 Alt- Ctrl-y

Edit:

Untuk menjawab pertanyaan yang Anda tambahkan ke sumber asli Anda:

Anda dapat menekan Alt- 0lalu berulang kali menekan Alt- .untuk menelusuri perintah sebelumnya (arg 0). Demikian pula Alt- -kemudian ulangi Alt- .akan memungkinkan Anda untuk melangkah melalui argumen berikutnya-ke-terakhir sebelumnya.

Jika tidak ada argumen yang sesuai pada baris tertentu dalam sejarah, bel akan berbunyi.

Jika ada kombinasi tertentu yang sering Anda gunakan, Anda dapat menentukan makro sehingga satu keystroke akan melakukannya. Contoh ini akan mengingat argumen kedua dari perintah sebelumnya dengan menekan Alt- Shift- Y. Anda dapat memilih keystroke yang tersedia yang Anda inginkan daripada yang ini. Anda dapat menekannya berulang kali untuk menelusuri yang sebelumnya.

Untuk mencobanya, masukkan makro di Bash prompt:

bind '"\eY": "\e2\e."'

Untuk membuatnya terus-menerus, tambahkan baris ini ke ~/.inputrcfile Anda :

"\eY": "\e2\e."

Sayangnya, ini sepertinya tidak berfungsi untuk arg 0 atau angka argumen negatif.


14
Saat mencari pintasan keyboard untuk bash / readline, saya suka berlari bind -lpdan melihat bindings saat ini.
Chad Skeeters

1
@ChadSkeeters: Dan -s(baru di Bash 4) mencantumkan makro yang dibuat menggunakan -x.
Dijeda sampai pemberitahuan lebih lanjut.

Perhatikan bahwa Anda dapat menggunakan argumen digit M-.juga: Alt-3 Alt-Ctrl-ymisalnya sama dengan menahan Altdan mengetik 3.. Jika Anda mengetik 3.beberapa kali tanpa melepaskan AltAnda pergi melalui argumen ketiga dari baris perintah sebelumnya.
hidangan penutup

essert essert I: Saya mengatakan banyak hal dalam paragraf kedua saya dan kemudian menunjukkan sebuah contoh.
Dijeda sampai pemberitahuan lebih lanjut.

@ChadSkeeters, terima kasih atas peringatan bahwa akan ada ratusan entri! Lol.
jdk1.0

309

!$ mendapatkan elemen terakhir dari argumen baris perintah sebelumnya.


115
!:3memberi Anda yang ketiga
Matt Dodge

108
! * membuat Anda semua em
menonton

75
!!memberi Anda seluruh perintah terakhir. Berguna jika Anda lupa menggunakannya sudo.
sama dengan

43
!:1-2membuat Anda semua kecuali yang terakhir dari 3 argumen
Tyler Brock

5
Hanya kata peringatan - jika Anda menggunakan argumen gabungan seperti echo foo{,bar} baz, perintah dicatat sebagai dicetak dan diperluas setelahnya. Dengan di atas, gunakan echo !:1setelah memutuskan untuk echo foo{,bar}dan kemudian berkembang keecho foo foobar
Sean

200

Untuk menggunakan argumen pertama, Anda dapat menggunakan !^atau!:1

Contoh:

$ echo a b c d e 
a b c d e
$ echo !^
echo a
a

$ echo a b c d e 
a b c d e
$ echo !:1
echo a
a

Karena pertanyaan Anda adalah tentang menggunakan argumen lain, berikut adalah beberapa argumen yang berguna:

!^      first argument
!$      last argument
!*      all arguments
!:2     second argument

!:2-3   second to third arguments
!:2-$   second to last arguments
!:2*    second to last arguments
!:2-    second to next to last arguments

!:0     the command
!!      repeat the previous line

Empat bentuk pertama lebih sering digunakan. Bentuknya !:2-agak kontra-intuitif, karena tidak termasuk argumen terakhir.


Apakah ada cara untuk mendapatkan item kedua terakhir? yaitu dapatkan file3dari mv file1 file2 file3 target/?
Charlie Harding

3
Saya sangat menyukai jawaban ini dan hanya demi kelengkapannya, saya sarankan untuk juga menambahkan baris yang menceritakan sintaks '! -2' yang memungkinkan Anda untuk mengakses sebelumnya ke perintah sebelumnya.
bbv

1
@bbv Juga untuk kelengkapan yang lebih lengkap, perintah '! 2' yang memungkinkan Anda mengakses entri kedua dalam riwayat (jika masih tersedia tergantung pada pengaturan riwayat Anda). Berguna jika Anda menampilkan nomor histori di setiap prompt.
816-8055

53

Saya suka @ larsman menjawab begitu banyak sehingga saya harus belajar lebih banyak. Menambahkan jawaban ini untuk membantu orang lain menemukan bagian halaman manual dan mengetahui untuk apa google:

$ man  -P 'less -p ^HISTORY\ EXPANSION' bash
<...>
Word Designators

Word designators are used to select desired words from the event.
A : separates the event specification from the word designator.
It may be omitted if the word designator begins with a ^, $, *, -,
or %.  Words are numbered from the beginning of the line, with the
first word being denoted by 0 (zero).  Words are inserted into the
current line separated by single spaces.

   0 (zero)
          The zeroth word.  For the shell, this is the command word.
   n      The nth word.
   ^      The first argument.  That is, word 1.
   $      The last argument.
   %      The word matched by the most recent ‘?string?’ search.
   x-y    A range of words; ‘-y abbreviates 0-y’.
   *      All of the words but the zeroth.
          This is a synonym for 1-$’.  
          It is not an error to use * if there is just one word in
          the event; the empty string is returned in that case.
   x*     Abbreviates x-$.
   x-     Abbreviates x-$ like x*, but omits the last word.

   If a word designator is supplied without an event
   specification, the previous command is used as the event.

18

! ^ mungkin perintah untuk argumen pertama. Saya tidak yakin apakah ada cara untuk mendapatkan tanggal.


7
itu!: n seperti yang disarankan di atas
Sergiu

Apakah ada cara untuk mendapatkan item terakhir ke-n, jadi seperti !:n, tetapi menghitung dari akhir dan bukan dari awal?
Charlie Harding

14

Anda juga bisa mendapatkan argumen dari perintah apa pun dalam riwayat Anda!


$ echo a b c d e f g
a b c d e f g
$ echo build/libs/jenkins-utils-all-0.1.jar
build/libs/jenkins-utils-all-0.1.jar
$ history | tail -5
  601  echo build/libs/jenkins-utils-all-0.1.jar
  602  history | tail -10
  603  echo a b c d e f g
  604  echo build/libs/jenkins-utils-all-0.1.jar
  605  history | tail -5
$ echo !-3:4
echo d
d
$ echo !604:1
echo build/libs/jenkins-utils-all-0.1.jar
build/libs/jenkins-utils-all-0.1.jar


4

Diuji pada Ubuntu 18.04


Untuk menyisipkan argumen sebelumnya:

  • Alt+ .: masukkan argumen terakhir dari perintah terakhir.
  • Alt+ #+ .: masukkan argumen terakhir #nth dari perintah terakhir.
  • Alt+ -, #, Alt+ ., Zsh: Alt + -+ #+ .: insert #nth argumen pertama dari perintah terakhir.

Di Linux Anda dapat mengulangi perintah untuk kembali dalam sejarah

Contoh:

Perintah terakhir adalah:

mv foo bar
  • Alt+ 0+ .: masukkan argumen pertama dari perintah terakhir =mv
  • Alt+ 2+ .: masukkan argumen 2 terakhir dari perintah terakhir =foo
  • up, Ctrl+ w: perintah terakhir tanpa kata terakhir =mv foo

Pintasan umum

  • Ctrl+ w: menghapus kata terakhir dari kursor
  • Alt+ d: menghapus kata berikutnya dari kursor
  • Ctrl+ k: memotong semuanya setelah kursor
  • Ctrl+ u, zsh: Alt + w: memotong segalanya sebelum kursor
  • zsh: Ctrl + u: memotong seluruh perintah (Dalam bash Anda dapat menggabungkan Ctrl+ u, Ctrl+ k)
  • Ctrl+ y: menempelkan karakter yang sebelumnya dipotong dengan Ctrl+ udan Ctrl+k
  • Ctrl+ _: batalkan edit terakhir (sangat berguna saat melebihi Ctrl+ w)
  • Ctrl+ left: pindah ke kata terakhir
  • Ctrl+ right: pindah ke kata berikutnya
  • homeatau Ctrl+ a: pindah ke mulai dari garis
  • endatau Ctrl+ e: pindah ke akhir baris

Untuk mengulangi argumen dalam perintah sebelumnya

hanya bekerja di zsh

jalankan atau tambahkan ini ke ~/.zshrc

autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey "^[:" copy-earlier-word

Sekarang gunakan Alt+ .untuk kembali seperti yang Anda inginkan, kemudian gunakan Alt+ :untuk beralih melalui argumen

Dengan asumsi perintah terakhir adalah

echo 1 2 3 4 5
  • Alt+ .:5
  • Alt+ .+ ::4
  • Alt+ .+ :+ ::3
  • Alt+ .+ :+ :+ ::2
  • Alt+ .+ :+ :+ :+ ::1
  • Alt+ .+ :+ :+ :+ :+ ::echo

sumber: https://stackoverflow.com/a/34861762/3163120

Untuk melihat semua pintasan tersedia

  • pesta: bind -lp
  • zsh: bindkey -L

Saya memperbarui ini di intisari ini https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9


1
Alt .di Zsh pada Mac mengetik 🤔
André Pena

1
ESC . berfungsi, meskipun hanya berfungsi untuk yang terakhir. Anda tidak dapat terus mengetik untuk kembali ke masa lalu. Mungkin ada baiknya memperbarui jawabannya. Terima kasih banyak.
André Pena

Anda dapat menjalankan bindkey -Ldi zsh untuk melihat semua pintasan diikat, mungkin itu akan membantu menunjukkan masalah, atau bahkan menemukan perintah berguna lainnya. Dalam kasus saya misalnya: penjilidan Alt .didefinisikan sebagai bindkey "^[." insert-last-word. Ctrl L(untuk menghapus layar) -> bindkey "^L" clear-screen. Alt+Ctrl h-> bindkey "^[^H" backward-kill-word(sama Ctrl wdengan menghapus kata terakhir)
Madacol

@ Madacol Saya juga bisa melihat pada tombol mengikat kata-kata sebelumnya yang bindkey "^[^_" copy-prev-word
disalin

3

Pada dasarnya memiliki penggunaan dalam menghentak sebelumnya (perintah ini) argumen .

Misalnya, jika perintah berikut dikeluarkan:

echo Hello, world how are you today?

maka, Hello,akan menjadi argumen pertama, dan today?yang keenam , yang adalah yang terakhir; artinya bisa dirujuk dengan mengetik:

Alt+6 diikuti oleh Ctrl-Alt-6


Ctrlsecara tradisional dilambangkan sebagai karakter hat ^ditambahkan di nama kunci, dan Altsebagai M-yang M eta awalan.

Jadi cara pintas di atas dapat didefinisikan ulang ^Myuntuk menarik.


Juga, ada pintasan substitusi topi di baris perintah:

echo Hello, world!

^Hello^Bye

Bye, world!

untuk mengganti string yang cocok pertama dengan perintah sebelumnya , yang berarti:

Hello, world! Hello, people!

^Hello^Bye

akan menghasilkan:

Bye, world! Hello, people!

meninggalkan pertandingan kedua ( hello) tidak berubah.

Catatan: Jangan menyisakan ruang di antara topi , atau operasi tidak akan berhasil.


Di atas hanyalah jalan pintas untuk:

!:s/Hello/Bye

substitusi event-level (*) untuk string yang pertama kali ditemukan (cocok) dalam perintah sebelumnya, sementara awalan bagian pertama dengan gsakelar akan berlaku untuk seluruh baris g secara lobal :

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

seperti biasanya dilakukan dalam perintah terkait lainnya seperti sed, vi, dan regex(ekspresi reguler) - cara standart untuk mencari ( string cocok ).

Tidak, Anda tidak dapat melakukannya !:sg/Hello/Byeatau di !:s/Hello/Bye/gsini, itulah sintaksnya !


  • ! untuk acara; Peristiwa mungkin dipahami sebagai output perintah atau operasi yang dilakukan dalam sejarah perintah.

Itulah yang saya pahami dengan menggunakannya sendiri dan mencoba sendiri dari apa yang saya baca dari berbagai sumber termasuk halaman manual, blog, dan forum.

Berharap itu akan memberikan beberapa cara misterius bash, shell Bourne-Again (permainan pada shshell, yang sendiri disebut Bourne shell setelah nama belakang penemunya), apa shell default di banyak distribusi termasuk server ( server OS ).


3

! ^ akan memberi Anda param pertama,! $ akan memberi Anda param terakhir,!: n akan memberi Anda elemen ke-n.


0

Metode yang dijelaskan di akhir jawaban yang diterima juga berfungsi dengan argumen nol untuk saya. Saya memiliki garis-garis ini di ~/.inputrc:

"\en": "\e0\e."
"\em": "\e1\e."
"\e,": "\e2\e."

\e2\e.memiliki keunggulan dibandingkan \e2\e\C-ydengan siklus melalui perintah sebelumnya jika ditekan berulang kali alih-alih memasukkan argumen kedua dari perintah sebelumnya beberapa kali.

Untuk memasukkan seluruh perintah sebelumnya, Anda bisa mengetik !!\e^. \e^adalah history-expand-line.


0

Jika Anda menggunakan mac Anda akan cenderung mendapatkan karakter yang diperluas dengan huruf ctrl +. Saya memiliki kunci hak-ruang-ruang-bar-opsi saya didefinisikan sebagai meta di terminal saya (iTerm2) diatur. Ini berarti saya menggunakan tombol untuk bernavigasi dengan kata dan menarik parameter dari perintah sebelumnya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.