Perintah Bash untuk menyalin sebelum kursor dan menempel setelahnya?

24

Saya tidak yakin bagaimana mengatakannya, tetapi saya sering menemukan diri saya mengetik perintah seperti ini:

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

Saya biasanya cukup mengetikkan path dua kali (dengan tab selesai) atau saya akan menyalin dan menempel path dengan kursor. Apakah ada beberapa bashfoo yang membuat ini lebih mudah untuk diketik?

pengguna1028270
sumber
2
Saya pikir maksud Anda bash-fu:)
kucing

Jawaban:

43

Ada sejumlah trik (saya pikir ada duplikat), tetapi untuk ini saya cenderung melakukannya

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

yang akan diperluas ke perintah Anda.

Ini dikenal sebagai ekspansi brace . Dalam bentuk yang digunakan di sini, {}ekspresi menentukan sejumlah string yang dipisahkan oleh koma. Ini "memperluas" seluruh /etc/prog/dir1/myconfig.yml{,.bak}ekspresi, mengganti {}bagian dengan masing-masing string pada gilirannya: string kosong, memberi /etc/prog/dir1/myconfig.yml, dan kemudian .bak, memberi /etc/prog/dir1/myconfig.yml.bak. Hasilnya adalah

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

Ekspresi ini dapat disarangkan:

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

menghasilkan

ab ac ade adf adg

Ada varian menggunakan angka untuk menghasilkan urutan:

echo {1..10}

menghasilkan

1 2 3 4 5 6 7 8 9 10

dan Anda juga dapat menentukan langkah:

echo {0..10..5}

menghasilkan

0 5 10
Stephen Kitt
sumber
sialan itu manis. Saya pikir saya bukan yang pertama bertanya, hanya pertanyaan yang sulit.
user1028270
Apa yang dilakukan koma di sana?
user1028270
5
Lihat Brace Expansion di manual: ini memisahkan nilai yang digunakan dalam ekspansi. Di sini kedua nilai tersebut adalah string kosong dan .bak.
Stephen Kitt
12

Perluasan sejarah dapat berguna untuk hal semacam ini (dengan asumsi sejarah bash diaktifkan).

Dalam contoh Anda, Anda bisa melakukan:

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

Di sini, !#merujuk ke baris saat ini, !#:1merujuk ke parameter 1 di baris saat ini,
dan !#:1.bakmerujuk ke parameter 1 di baris saat ini dengan '.bak' ditempelkan di akhir.

Ketika Anda memiliki specifier sejarah yang diketik, Anda dapat menggunakan Ctrl+ Alt+ Euntuk memperluasnya ke nilai sebenarnya jika Anda ingin misalnya memeriksa ulang atau memodifikasi nama file.

Bagian "Riwayat Perluasan" di halaman bash man memiliki info lebih lanjut.

Buang air besar
sumber
8

Mirip dengan jawaban progo, tetapi agak lebih sederhana: C-wmemotong ("membunuh") kata di sebelah kiri kursor, C-ymenyisipkan ("menyentak") lagi.

$ 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
sumber
2
Juga patut dicatat bahwa Anda dapat melakukan ini dengan beberapa kata secara berurutan (jika nama file Anda memiliki spasi, misalnya) dan Cy akan menempelkan semuanya, selama Anda belum memindahkan kursor atau mengetik apa pun di antaranya. Setiap campuran dari perintah penghapusan kecuali penghapusan satu karakter (mis. Backspace / del / ctrl-d) berfungsi dengan ini.
Random832
6

Anda juga dapat memotong-paste (kill-yank dalam istilah emacs / bash) dari commandline untuk menggandakan bagian-bagian untuk diedit.

M-dmembunuh maju sampai batas kata, dan Anda dapat membunuh teks beberapa kali dan mereka semua disatukan menjadi satu 'tempel' untuk menarik. Mudah!

Tarik ini semua kembali ke baris perintah di kursor oleh C-y. Jadi jika Anda memiliki garis seperti ini (elemen blok █ menunjukkan posisi kursor):

$ 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

Apa pun yang Anda inginkan, membiasakan diri dengan apa yang ditawarkan bash di departemen kunci interaktif akan bermanfaat. http://web.mit.edu/gnu/doc/html/features_7.html

unperson325680
sumber
6

Dalam tcshatau zsh, Alt+Ctrl+_dalam emacsmode ( copy-prev-wordwidget) memasukkan kata terakhir, jadi

cp Alt+Ctrl+_.back jalur yang sangat panjang

bashmemiliki copy-backward-wordwidget (tidak terikat ke tombol apa pun secara default) tetapi itu hanya menyalin kata ke buffer cincin, Anda harus juga menekan Ctrl-Y(dalam emacsmode) untuk menariknya. Tetapi Anda bisa melakukannya:

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

Untuk Alt+Ctrl+_melakukan copy / snarf dan paste / yank seperti di tcsh/ zsh.

Stéphane Chazelas
sumber