Bagaimana cara cepat mengubah kata pertama dalam perintah Bash?

44

Saya ingin sedikit meningkatkan alur kerja saya dengan Bash, dan saya sadar saya sering ingin mengeksekusi perintah yang sama ke executable yang berbeda.

Beberapa contoh:

Git (di mana saya ingin dengan cepat mengubah kata kedua):

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

Cat / rm (di mana hanya kata pertama yang harus diubah):

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

Saya tahu saya dapat menekan Ctrl+ alalu Deluntuk menghapus kata pertama, tetapi saya bertanya-tanya apakah ada cara yang lebih cepat untuk melakukannya.

sekarang
sumber
Sejujurnya, saya pikir paling aman menggunakan Ctrl + a dan menghapus. Jelas tidak terlalu lambat.
agweber

Jawaban:

56

!$ memperluas kata terakhir dari perintah Anda sebelumnya.

Jadi Anda bisa melakukan:

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

rm !$

atau:

git diff foo/bar.c

git checkout !$

Contoh Anda kebetulan hanya mengulangi kata terakhir, jadi !$berfungsi dengan baik. Jika Anda benar-benar memiliki banyak argumen yang ingin Anda ulangi, dan Anda hanya ingin mengubah kata pertama, Anda bisa menggunakan !*, yang meluas ke semua kata dari perintah sebelumnya kecuali zeroth.

Lihat bagian "EKSPANSI SEJARAH" dari bashhalaman manual. Ada banyak fleksibilitas di sana.

Spiff
sumber
16
Benar dan benar. Saya hanya ingin memberi peringatan : dengan !$Anda tidak memiliki kontrol visual penuh dari garis yang Anda jalankan . Ini terkadang bisa berbahaya. Khususnya jika Anda mengalami kesalahan cetak. Dibutuhkan dari historyapa yang berkembang. Jadi jika Anda menulis perintah terakhir dengan spasi kosong di awal, mungkin perintah ini tidak akan selesai dalam sejarah. Ketika Anda akan menjalankan perintah baru Anda dengan !$shell tidak akan mengambil parameter dari baris perintah terakhir yang diketik tetapi hanya dari yang terakhir dari sejarah. Di sini sama lebih banyak kata.
Hastur
1
@Hastur Anda dapat mengatur shell untuk memperluas riwayat pada tab atau saat masuk untuk mencegah kecelakaan.
Aduh
2
@Hastur itu sebabnya Anda perlu menekan intro dua kali dalam zsh (promosi tak tahu malu)
Braiam
@Hastur - Ketika saya memiliki keraguan tentang apa yang akan terjadi atau saya terlambat menyadari saya harus melakukan sesuatu yang lain sebelum menjalankan sesuatu yang lama saya baru saja mengetik, saya pergi ke awal baris dan menambahkan #atau echo jadi saya bisa lihat itu dan itu masuk ke sejarah sehingga saya bisa mendapatkannya kembali dan menjalankannya lagi tanpa awalan penonaktifan.
Joe
28

Ctrl+ auntuk pergi ke awal baris, lalu Alt+ duntuk menghapus kata pertama.

jjlin
sumber
9
Pintasan kata delete sebenarnya adalah Meta + d, dan Meta biasanya dipetakan ke Alt pada mesin Linux. Pada platform di mana hal ini tidak terjadi, alternatif untuk mendapatkan pengubah Meta adalah dengan menggunakan Escape sebagai awalan. Lihat en.wikipedia.org/wiki/Meta_key
Gustavo Giráldez
2
@ GustavoGiráldez jika Anda ingin masuk lebih dalam, maka Meta+Dhanya valid jika emacsdiaktifkan (melalui set -o emacsatau secara default). Ini tidak akan berfungsi dalam editor -mode yang lebih rendah atau jika emacsdinonaktifkan.
TC1
Di banyak terminal (karena ini adalah hal terminal dan bukan hal Bash), kunci rumah juga akan pergi ke awal baris. Banyak laptop memetakan Fn + Kiri ke tombol beranda. Demikian pula, tombol putus biasanya akan menuju akhir baris. Saya belum menggunakan terminal emulator yang tidak mendukung hotkey ini.
Kat
1
@ Mike Di sisi lain, C-adan M-djauh lebih cepat untuk mengetik jika tangan Anda sudah dalam posisi mengetik.
jjlin
@ Mike Ini adalah hal bash. Ketik catdan bandingkan apa yang Anda dapatkan saat menekan Home (di ^[[Hsini) dan saat menekan Ctrl + a ( ^A).
Jonas Schäfer
17

Saya tidak yakin apakah itu benar-benar akan lebih cepat atau tidak, tetapi lihat artikel ini, khususnya poin # .3:

  1. Ganti string dari perintah sebelumnya menggunakan ^ str1 ^ str2 ^

Pada contoh berikut, pertama-tama kita menjalankan perintah ls untuk memverifikasi file. Kemudian kami menyadari bahwa kami ingin melihat konten file. Daripada mengetikkan seluruh nama file lagi, kita bisa mengganti "ls" pada perintah sebelumnya dengan "cat" seperti yang ditunjukkan di bawah ini.

$ ls /etc/cron.daily/logrotate

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

Alt+.

Jika Anda hanya perlu mengulangi bagian terakhir dari salah satu perintah sebelumnya, Anda dapat menggunakan Alt+ .yang akan menempelkan argumen terakhir yang diambil dari baris terakhir dari sejarah.

Jika ditekan lebih dari satu kali akan menggantikan apa yang baru saja disisipkan dengan argumen terakhir dari baris sebelumnya ...

Misal jika 2 perintah terakhir adalah:

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

Dalam shell saya menulis rmdan saya tekan Alt+ .maka akan muncul:

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

jika saya menekan lagi Alt+ .itu akan muncul sebagai gantinya

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

dan seterusnya...

Cepat
sumber
Tidak yakin mengapa tetapi ini tidak berfungsi pada konsol Mac saya.
lulalala
Di sini ada cara pintas keyboard yang dikenal untuk bekerja dengan bash. BTW Anda yakin menggunakan bash sebagai shell ?
Hastur
1
Saya kira ini adalah masalah Mac. Saat saya mengetik yang saya dapatkan
lulalala
12

Selain jawaban @jjlin, Anda mungkin tertarik dengan kiat-kiat berikut:

  • Ctrl+ wmenghapus kata di sebelah kiri Anda
  • Ctrl+ kmenghapus dari kursor ke akhir baris perintah
  • Ctrl+ umenghapus dari kursor ke awal baris perintah
  • Alt+ bmemindahkan kursor satu kata ke belakang
  • Alt+ fmemindahkan kursor satu kata ke depan
  • $_ berisi argumen terakhir dari baris perintah sebelumnya

Untuk lebih lanjut tentang ini, lihat bagian "Nama Perintah Readline" dari halaman bashmanual.

misalnya:

cat foo/is/a/very/long/path/to/bar.c
rm $_
maiki
sumber
Itu tip yang bagus, tetapi tidak menjawab pertanyaan.
Aduh
@ slhck IMHO tidak karena judul pertanyaan tidak cocok dengan contoh yang diberikan. Jika kita fokus pada contoh, seperti yang saya lakukan, judulnya adalah "Bagaimana cara cepat mengubah kata dalam perintah bash?" . Ini juga mengapa jawaban saya adalah "di samping @jjlin". Tapi saya kira pertanyaannya harus diklarifikasi.
maiki
OP selalu ingin menghapus (menukar) nkata-kata pertama dalam perintah, dengan n = 1dalam contoh pertama dan n = 2yang kedua. Jawaban jjlin menunjukkan cara menghapus kata pertama (dan dengan menerapkan kembali cara pintas, hapus hingga nkata - kata). Jawaban Anda mencantumkan beberapa pintasan Bash (yang memang bermanfaat), tetapi tidak ada yang efisien untuk menghapus nkata-kata pertama .
slhck
Hm, membaca lagi, $_parameter mungkin akan berfungsi jika hanya ada satu argumen (yaitu jika di n = m - 1mana mjumlah total argumen). Sisa dari cara pintas tidak relevan dengan pertanyaan sekalipun.
slhck
@ slhck Demi berdebat saya sudah membaca contoh pertama sebagai "ganti kata 2" :-)
maiki
8

Jika Anda mahir dalam vi, Anda dapat mengaktifkan vi binding di bash (kebanyakan shell?) Dengan menggunakan perintah set -o vi. Kemudian, Anda dapat menggunakan tombol vi normal untuk mengedit perintah Anda. Pada contoh pertama Anda, Anda bisa ^wcwmenghapus "diff", lalu mengubahnya menjadi checkout.

Mungkin tidak ada gunanya mempelajari vi keybindings hanya dengan mengedit baris perintah, tetapi jika Anda sudah mengetahuinya, itu adalah pendorong produktivitas yang rapi.

Kacau0
sumber
Saya belajar di Kornshell, begitu set -o vijuga cara saya hidup! Saya bahkan melakukan ini di bash saya meminta juga.
bgStack15
bindkey -vuntuk zsh. Esc 0 c w
user530873
6

Ada banyak cara untuk menguliti kucing ini!

Untuk mengganti string tertentu, ^old^new^extraakan mengambil perintah Anda sebelumnya, ganti olddengan new, dan tambahkan extra. Anda dapat berhenti sedini mungkin; mis. ^oldakan mengganti olddengan string kosong dan menambahkan string kosong (pada dasarnya menghapus olddan tidak melakukan apa-apa lagi).

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

Varian yang sangat berguna dari ini:

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

Untuk mengganti kata tertentu, Anda dapat menggunakan !m:n-puntuk merujuk kata n- kata melalui pperintah m(gunakan angka negatif untuk menghitung mundur dari perintah saat ini). Anda bisa menghilangkan -pbagian untuk merujuk ke satu kata, dan menghilangkan :m-pbagian untuk merujuk ke seluruh perintah. Bentuk khusus !!untuk !-1, !$untuk kata terakhir dari perintah sebelumnya, dan !*untuk argumen (semuanya kecuali kata 0) dari perintah sebelumnya cukup berguna.

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

Saya sering menggunakan keduanya; zsh sangat baik di sini, karena tab tab akan memperluas barang rahasia untuk memastikan Anda melakukannya dengan benar.

Ada juga banyak cara untuk melakukan ini dengan pengeditan baris. Bacalah tentang keybindings shell Anda.

Daniel Wagner
sumber
-2

Sebagian besar program terminal mendukung ...

  • Tekan <Up-Arrow>seperlunya untuk menampilkan kembali salah satu baris perintah sebelumnya dari riwayat.
    • Tekan <Down-Arrow>seperlunya untuk bergerak maju melalui daftar riwayat.
  • Tekan <Left-Arrow>seperlunya untuk memindahkan kursor ke akhir kata kedua.
  • Tekan <Backspace>seperlunya untuk menghapus kata kedua.
  • Ketikkan kata kedua pengganti.
    • Tekan <Right-Arrow>/ <Left-Arrow>jika perlu untuk memposisikan lebih banyak perubahan.
  • Hit <RETURN>untuk menjalankan perintah

Jika baris perintah yang Anda inginkan bukan yang terbaru, lakukan pencarian balik-i- <Ctrl-r>seperti yang dijelaskan dalam pertanyaan ...
Apakah ada cara menggunakan ctrl-r setelah mengetikkan bagian dari perintah di bash?
Kemudian edit melalui tombol panah sesuai kebutuhan.

DocSalvager
sumber
-3

Apa yang saya lakukan (Ubuntu / bash):

1) Arrow uphei untuk mengembalikan perintah sebelumnya
2) Homekunci untuk kembali ke awal
3) Ubah perintah sesuai kebutuhan.

Idiot-proof dan sangat berguna untuk perintah multi-line.

Vorac
sumber