Làm thế nào để sử dụng các đối số từ lệnh trước?


287

Tôi biết rằng Esc+ .cung cấp cho bạn đối số cuối cùng của lệnh cuối cùng.

Nhưng tôi quan tâm đến lập luận đầu tiên của lệnh cuối cùng. Có một ràng buộc quan trọng để làm như vậy?

Trên cùng một dòng, có một cách chung để nhận đối số thứ n từ lệnh cuối cùng không? Tôi biết rằng trong một tập lệnh bash, bạn có thể sử dụng $0, $1v.v., nhưng chúng không hoạt động trên dòng lệnh.

Ngoài ra, những gì về việc lặp qua đối số 0 của các lệnh trước đó, như chúng ta có thể làm gì với đối số cuối cùng bằng cách nhấn liên tục Esc+ .?

Câu trả lời:


284

Giống như M-.(meta-dot hoặc esc-dot hoặc alt-dot) là hàm readline yank-last-arg, M-C-y(meta-control-y hoặc esc-ctrl-y hoặc ctrl-alt-y) là hàm readline yank-nth-arg. Không chỉ định n, nó đưa ra đối số đầu tiên của lệnh trước đó.

Để chỉ định một đối số, nhấn Escape và một số hoặc giữ Alt và nhấn một số. Bạn có thể làm Alt- -để bắt đầu chỉ định số âm sau đó nhả Alt và nhấn chữ số (số này sẽ được tính từ cuối danh sách các đối số.

Thí dụ:

Nhập lệnh sau

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

Bây giờ tại dấu nhắc tiếp theo, nhập echo(với khoảng trắng sau), sau đó

Nhấn Alt- Ctrl- yvà bây giờ bạn sẽ thấy:

$ echo a

không cần nhấn Enter, hãy làm như sau

Nhấn Alt- 3 Alt- Ctrl-y

Nhấn Alt- - 2 Alt- Ctrl-y

Bây giờ bạn sẽ thấy:

$ echo ace

Nhân tiện, bạn có thể đặt dòng echotrên bằng cách chọn đối số 0:

Nhấn Alt- 0 Alt- Ctrl-y

Biên tập:

Để trả lời câu hỏi bạn đã thêm vào bản gốc của mình:

Bạn có thể nhấn Alt- 0sau đó nhấn liên tục Alt- .để chuyển qua các lệnh trước đó (arg 0). Tương tự Alt- -sau đó lặp lại Alt- .sẽ cho phép bạn bước qua các đối số tiếp theo trước đó.

Nếu không có lập luận thích hợp về một dòng cụ thể trong lịch sử, tiếng chuông sẽ vang lên.

Nếu có một sự kết hợp cụ thể mà bạn sử dụng thường xuyên, bạn có thể xác định một macro để một tổ hợp phím sẽ thực hiện nó. Ví dụ này sẽ gọi lại đối số thứ hai từ các lệnh trước bằng cách nhấn Alt- Shift- Y. Bạn có thể chọn bất kỳ tổ hợp phím có sẵn nào bạn thích thay vì tổ hợp phím này. Bạn có thể nhấn nó nhiều lần để bước qua những cái trước đó.

Để dùng thử, hãy nhập macro tại dấu nhắc Bash:

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

Để làm cho nó liên tục, thêm dòng này vào ~/.inputrctệp của bạn :

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

Thật không may, điều này dường như không hoạt động đối với các số đối số 0 hoặc đối số phủ định.


14
Khi tìm kiếm các phím tắt cho bash / readline, tôi thích chạy bind -lpvà xem các ràng buộc hiện tại.
Chad Skeeter

1
@ChadSkeeter: Và -s(mới trong Bash 4) liệt kê các macro được tạo bằng cách sử dụng -x.
Tạm dừng cho đến khi có thông báo mới.

Lưu ý rằng bạn cũng có thể sử dụng đối số chữ số M-.: Alt-3 Alt-Ctrl-yví dụ như bằng cách giữ Altvà gõ 3.. Nếu bạn gõ 3.nhiều lần mà không giải phóng, Altbạn sẽ đi qua các đối số thứ ba của các dòng lệnh trước đó.
tráng miệng

@datcher: Tôi nói nhiều như vậy trong đoạn thứ hai của mình và sau đó đưa ra một ví dụ.
Tạm dừng cho đến khi có thông báo mới.

@ChadSkeeter, cảm ơn vì đã cảnh báo rằng sẽ có hàng trăm mục! Cười lớn.
jdk1.0

309

!$ được phần tử cuối cùng của đối số dòng lệnh trước đó.


115
!:3giúp bạn trở thành người thứ ba
Matt Dodge

108
! * giúp bạn có tất cả các em
hoành thánh

75
!!giúp bạn có toàn bộ lệnh cuối cùng. Hữu ích nếu bạn quên sử dụng sudo.
Un3qual

43
!:1-2có được tất cả các bạn trừ 3 đối số cuối cùng
Tyler Brock

5
Chỉ cần một lời cảnh báo - nếu bạn sử dụng các đối số kết hợp như echo foo{,bar} baz, lệnh sẽ được ghi lại dưới dạng in và mở rộng sau đó. Với cách trên, sử dụng echo !:1sau khi giải quyết echo foo{,bar}và sau đó mở rộng thànhecho foo foobar
Sean

200

Để sử dụng đối số đầu tiên, bạn có thể sử dụng !^hoặc!:1

Thí dụ:

$ 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

Vì câu hỏi của bạn là về việc sử dụng bất kỳ đối số nào khác, đây là một số đối số hữu ích:

!^      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

Bốn hình thức đầu tiên thường được sử dụng. Biểu mẫu !:2-có phần phản trực giác, vì nó không bao gồm đối số cuối cùng.


Có cách nào để có được món đồ thứ hai không? tức là lấy file3từ mv file1 file2 file3 target/đâu?
Charlie Harding

3
Tôi thích câu trả lời này rất nhiều và chỉ vì mục đích hoàn chỉnh, tôi đề nghị cũng thêm một dòng nói về cú pháp '! -2' cho phép bạn truy cập vào lệnh trước đó.
bbv

1
@bbv Ngoài ra để hoàn thiện hơn nữa, lệnh '! 2' cho phép bạn truy cập mục nhập thứ hai trong lịch sử (nếu nó vẫn khả dụng tùy thuộc vào cài đặt lịch sử của bạn). Hữu ích nếu bạn hiển thị số lịch sử trong mỗi dấu nhắc.
816-8055

53

Tôi thích câu trả lời của @larsmans rất nhiều, tôi phải tìm hiểu thêm. Thêm câu trả lời này để giúp người khác tìm phần trang man và biết google để làm gì:

$ 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

! ^ có thể là lệnh cho đối số đầu tiên. Tôi không chắc có cách nào để có được thứ n không.


7
đó là !: n như đề xuất ở trên
Sergiu

Có cách nào để có được mục cuối cùng thứ n, như vậy !:n, nhưng đếm từ cuối chứ không phải bắt đầu?
Charlie Harding

14

Bạn cũng có thể nhận được các đối số từ bất kỳ lệnh nào trong lịch sử của bạn!


$ 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

Đã thử nghiệm trên Ubuntu 18.04


Để chèn các đối số trước:

  • Alt+ .: chèn đối số cuối cùng từ lệnh cuối cùng.
  • Alt+ #+ .: chèn #nth đối số cuối cùng từ lệnh cuối cùng.
  • Alt+ -, #, Alt+ ., Zsh: Alt + -+ #+ .: chèn #nth số đầu tiên từ lệnh cuối cùng.

Trong Linux, bạn có thể lặp lại các lệnh để quay lại lịch sử

Thí dụ:

Lệnh cuối cùng là:

mv foo bar
  • Alt+ 0+ .: chèn đối số đầu tiên của lệnh cuối =mv
  • Alt+ 2+ .: chèn đối số thứ 2 cuối cùng của lệnh cuối =foo
  • up, Ctrl+ w: lệnh cuối cùng không có từ cuối cùng =mv foo

Phím tắt chung

  • Ctrl+ w: xóa từ cuối cùng khỏi con trỏ
  • Alt+ d: xóa từ tiếp theo khỏi con trỏ
  • Ctrl+ k: cắt mọi thứ sau con trỏ
  • Ctrl+ u, zsh: Alt + w: cắt mọi thứ trước khi con trỏ
  • zsh: Ctrl + u: cắt toàn bộ lệnh (Trong bash, bạn có thể kết hợp Ctrl+ u, Ctrl+ k)
  • Ctrl+ y: dán các ký tự được cắt trước đó bằng Ctrl+ uCtrl+k
  • Ctrl+ _: hoàn tác chỉnh sửa lần cuối (rất hữu ích khi vượt quá Ctrl+ w)
  • Ctrl+ left: chuyển đến từ cuối cùng
  • Ctrl+ right: chuyển sang từ tiếp theo
  • homehoặc Ctrl+ a: di chuyển đến đầu dòng
  • endhoặc Ctrl+ e: di chuyển đến cuối dòng

Để lặp qua các đối số trong lệnh trước đó

chỉ hoạt động trong zsh

chạy hoặc thêm cái này vào ~/.zshrc

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

Bây giờ sử dụng Alt+ .để quay lại như bạn muốn, sau đó sử dụng Alt+ :để lặp qua các đối số

Giả sử lệnh cuối cùng là

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

nguồn: https://stackoverflow.com/a/34861762/3163120

Để xem tất cả các phím tắt có sẵn

  • bash bind -lp
  • zsh: bindkey -L

Tôi đang cập nhật thông tin này trong ý chính này https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9


1
Alt .trên Zsh trên Mac đang gõ 🤔
André Pena

1
Trốn hoạt động, mặc dù nó chỉ hoạt động cho người cuối cùng. Bạn không thể tiếp tục gõ để quay ngược thời gian. Có lẽ nó sẽ có giá trị cập nhật câu trả lời. Cảm ơn rât nhiều.
André Pena

Bạn có thể chạy bindkey -Ltrong zsh để xem tất cả các phím tắt được liên kết, có thể nó sẽ giúp xác định chính xác vấn đề hoặc thậm chí tìm các lệnh hữu ích khác. Trong trường hợp của tôi ví dụ: ràng buộc Alt .được định nghĩa là bindkey "^[." insert-last-word. Ctrl L(để xóa màn hình) -> bindkey "^L" clear-screen. Alt+Ctrl h-> bindkey "^[^H" backward-kill-word(giống như Ctrl wxóa từ cuối cùng)
Madacol

@Madacol Tôi cũng có thể thấy trên các khóa ràng buộc bản sao được đề cập trước đó là bindkey "^[^_" copy-prev-word
kikeenrique

3

Về cơ bản, nó có một cách sử dụng trong các đối số (lệnh) trước đó .

Chẳng hạn, nếu lệnh sau được ban hành:

echo Hello, world how are you today?

sau đó, Hello,sẽ là đối số đầu tiên, và today?các thứ sáu , đó là người cuối cùng; có nghĩa là nó có thể được tham chiếu bằng cách gõ:

Alt+6 theo dõi bởi Ctrl-Alt-6


Ctrltheo truyền thống được ký hiệu là một ký tự mũ được đặt ^trước tên khóa và AltM-đó là tiền tố M eta .

Vì vậy, các phím tắt ở trên có thể được xác định lại như là ^Myyank.


Ngoài ra, có phím tắt thay thế trong dòng lệnh:

echo Hello, world!

^Hello^Bye

Bye, world!

để thay thế chuỗi khớp đầu tiên của lệnh trước đó , nghĩa là:

Hello, world! Hello, people!

^Hello^Bye

sẽ dẫn đến:

Bye, world! Hello, people!

để lại trận đấu thứ hai ( hello) không thay đổi.

Lưu ý: Không chừa khoảng trống giữa các mũ hoặc thao tác sẽ không hoạt động.


Trên đây chỉ là một phím tắt cho:

!:s/Hello/Bye

thay thế cấp độ sự kiện (*) cho chuỗi tìm thấy (khớp) đầu tiên trong lệnh trước đó, trong khi tiền tố phần đầu tiên với công gtắc sẽ áp dụng cho toàn bộ dòng g lobally :

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

như thường được thực hiện trong các lệnh liên quan khác như sed, vivà trong regex(biểu thức chính quy) - một cách độc lập để tìm kiếm ( khớp chuỗi ).

Không, bạn không thể làm !:sg/Hello/Byehoặc !:s/Hello/Bye/gở đây, đó là cú pháp !


  • ! dành cho các sự kiện; sự kiện có thể được hiểu là đầu ra lệnh hoặc hoạt động được thực hiện trong lịch sử lệnh.

Đó là những gì tôi hiểu bằng cách tự mình sử dụng và tự mình thử mọi thứ từ những gì tôi đọc được từ nhiều nguồn khác nhau bao gồm các trang hướng dẫn, blog và diễn đàn.

Hy vọng nó sẽ làm sáng tỏ những cách bí ẩn bash, shell Bourne-Again (một trò chơi trên shvỏ, được gọi là shell Bourne sau tên họ của nhà phát minh), vỏ mặc định trong nhiều bản phân phối bao gồm cả máy chủ ( hệ điều hành máy chủ ).


3

! ^ sẽ giúp bạn có được thông số đầu tiên ,! $ sẽ giúp bạn có được thông số cuối cùng ,!: n sẽ giúp bạn có được phần tử thứ n.


0

Phương pháp được mô tả ở cuối câu trả lời được chấp nhận cũng hoạt động với đối số zeroth đối với tôi. Tôi có những dòng này trong ~/.inputrc:

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

\e2\e.có lợi thế hơn \e2\e\C-ylà nó quay vòng qua các lệnh trước nếu nó được nhấn liên tục thay vì chèn đối số thứ hai của lệnh trước đó nhiều lần.

Để chèn toàn bộ lệnh trước đó, bạn có thể gõ !!\e^. \e^history-expand-line.


0

Nếu bạn đang sử dụng máy Mac, bạn sẽ có xu hướng nhận được các ký tự mở rộng bằng chữ ctrl +. Tôi có khóa tùy chọn thanh không gian bên phải được xác định là meta trong thiết bị đầu cuối của mình (iTerm2) được thiết lập. Điều này có nghĩa là tôi sử dụng phím để điều hướng bằng từ và kéo các tham số từ các lệnh trước đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.