Làm thế nào để nhanh chóng thay đổi từ đầu tiên trong lệnh Bash?


44

Tôi muốn cải thiện quy trình làm việc của mình một chút với Bash và tôi nhận ra rằng tôi thường muốn thực hiện cùng một lệnh cho một tệp thực thi khác.

Vài ví dụ:

Git (nơi tôi muốn thay đổi nhanh từ thứ hai):

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

Cat / rm (chỉ thay đổi từ đầu tiên):

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

Tôi biết tôi có thể nhấn Ctrl+ asau đó Delđể xóa từ đầu tiên, nhưng tôi tự hỏi liệu có cách nào nhanh hơn để làm điều đó không.



Thành thật mà nói, tôi nghĩ an toàn nhất là chỉ sử dụng Ctrl + a và xóa. Nó chắc chắn không chậm lắm.
agweber

Câu trả lời:


56

!$ mở rộng đến từ cuối cùng của lệnh trước đó của bạn.

Vì vậy, bạn có thể làm:

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

rm !$

hoặc là:

git diff foo/bar.c

git checkout !$

Ví dụ của bạn đã xảy ra chỉ lặp lại từ cuối cùng, vì vậy !$làm việc tốt. Nếu bạn thực sự có rất nhiều đối số mà bạn muốn lặp lại và bạn chỉ muốn thay đổi từ đầu tiên, bạn có thể sử dụng !*, nó mở rộng ra tất cả các từ của lệnh trước trừ zeroth.

Xem phần "MỞ RỘNG LỊCH SỬ" của bashtrang người đàn ông. Có rất nhiều sự linh hoạt ở đó.


16
Đúng và đúng. Tôi chỉ muốn đưa ra một cảnh báo : với !$bạn không có quyền kiểm soát trực quan đầy đủ về dòng bạn đang chạy . Điều này đôi khi có thể gây hại. Đặc biệt nếu bạn phải chịu một sai lầm. Nó cần từ historynhững gì để mở rộng. Vì vậy, nếu bạn viết lệnh cuối cùng với một khoảng trắng ở đầu, có thể lệnh này sẽ không hoàn thành trong lịch sử. Khi bạn sẽ thực thi lệnh mới của mình với !$shell sẽ không lấy các tham số từ dòng lệnh cuối cùng được gõ mà chỉ từ cuối cùng của lịch sử. Ở đây cùng nhiều từ hơn.
Hastur

1
@Hastur Bạn có thể đặt vỏ của mình để mở rộng lịch sử trên tab hoặc khi vào để tránh tai nạn.
slhck

2
@Hastur đó là lý do tại sao bạn cần nhấn intro hai lần trong zsh (khuyến mãi không biết xấu hổ)
Braiam

@Hastur - Khi tôi có bất kỳ nghi ngờ gì về những gì sẽ xảy ra hoặc tôi nhận ra rằng tôi phải làm một cái gì đó khác trước khi chạy một cái gì đó dài mà tôi vừa gõ, tôi đi đến đầu dòng và thêm một #hoặc echo để tôi có thể nhìn thấy nó và nó đi vào lịch sử để tôi có thể lấy lại ngay và chạy lại mà không cần tắt tiền tố.
Joe

28

Ctrl+ ađể đi đến đầu dòng, sau đó Alt+ dđể xóa từ đầu tiên.


9
Phím tắt từ thực sự là Meta + d và Meta thường được ánh xạ tới Alt trên các máy Linux. Trên các nền tảng không phải là trường hợp này, một giải pháp thay thế để có được công cụ sửa đổi Meta là sử dụng Escape làm tiền tố. Xem en.wikipedia.org/wiki/Meta_key
Gustavo Giráldez

2
@ GustavoGiráldez nếu bạn muốn đi sâu, thì Meta+Dchỉ hợp lệ nếu emacsđược bật (thông qua set -o emacshoặc đơn giản là theo mặc định). Nó sẽ không hoạt động trong trình soạn thảo kém hơn hoặc nếu emacsbị vô hiệu hóa.
TC1

Trong nhiều thiết bị đầu cuối (vì đây là thiết bị đầu cuối chứ không phải vật Bash), phím home cũng sẽ đi đến đầu dòng. Nhiều máy tính xách tay ánh xạ Fn + Trái với phím home. Tương tự, khóa kết thúc thường sẽ đi đến cuối dòng. Tôi vẫn chưa sử dụng trình giả lập thiết bị đầu cuối không hỗ trợ các phím nóng này.
Kat

1
@Mike Mặt khác, C-aM-dgõ nhanh hơn nhiều nếu tay bạn đã ở vị trí gõ.
jjlin

@Mike Đây là một điều bash. Nhập catvà so sánh những gì bạn nhận được khi nhấn Home ( ^[[Htại đây) và khi nhấn Ctrl + a ( ^A).
Jonas Schäfer

17

Tôi không chắc liệu nó có thực sự nhanh hơn hay không, nhưng hãy xem bài viết này, đặc biệt là điểm # .3:

  1. Thay thế một chuỗi từ lệnh trước bằng ^ str1 ^ str2 ^

Trong ví dụ sau, đầu tiên chúng tôi đã thực thi lệnh ls để xác minh một tệp. Sau đó chúng tôi nhận ra rằng chúng tôi muốn xem nội dung của tập tin. Thay vì gõ lại toàn bộ tên tập tin, chúng ta chỉ có thể thay thế tên lsv trong lệnh trước đó bằng cách sử dụng chú mèo mèo như hình dưới đây.

$ ls /etc/cron.daily/logrotate

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

15

Alt+.

Nếu bạn chỉ cần lặp lại phần cuối của một trong các lệnh trước đó, bạn có thể sử dụng Alt+ .sẽ dán đối số cuối cùng được lấy từ dòng cuối cùng của lịch sử.

Nếu được nhấn nhiều lần sẽ thay thế những gì vừa dán bằng đối số cuối cùng của dòng trước ...

Ví dụ: nếu 2 lệnh cuối cùng là:

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

Trong shell tôi viết rmvà tôi nhấn Alt+ .nó sẽ xuất hiện:

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

nếu tôi nhấn lần nữa Alt+ .nó sẽ xuất hiện thay thế

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

và v.v.


Không chắc chắn tại sao nhưng điều này không hoạt động trên bảng điều khiển Mac của tôi.
lulalala

Ở đây có các phím tắt được biết là làm việc với bash. BTW Bạn có chắc là bạn đang sử dụng bash như shell ?
Hastur

1
Tôi đoán đây là một điều Mac. Khi tôi gõ mà tôi nhận được
lulalala


12

Ngoài câu trả lời @jjlin, bạn có thể quan tâm theo các mẹo sau:

  • Ctrl+ wxóa từ bên trái của bạn
  • Ctrl+ kxóa từ con trỏ đến cuối dòng lệnh
  • Ctrl+ uxóa từ con trỏ đến đầu dòng lệnh
  • Alt+ bdi chuyển con trỏ lùi một từ
  • Alt+ fdi chuyển con trỏ về phía trước một từ
  • $_ chứa đối số cuối cùng của dòng lệnh trước

Để biết thêm về những điều này, hãy tra cứu phần "Tên lệnh đọc" của bashtrang chủ.

ví dụ:

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

Đó là những lời khuyên hay, nhưng họ không trả lời câu hỏi.
slhck

@slhck IMHO nó làm bởi vì tiêu đề câu hỏi không phù hợp với các ví dụ đã cho. Nếu chúng ta tập trung vào các ví dụ, như tôi đã làm, tiêu đề sẽ là "Làm thế nào để nhanh chóng thay đổi một từ trong lệnh bash?" . Đây cũng là lý do tại sao câu trả lời của tôi là "ngoài câu trả lời của @jjlin". Nhưng tôi đoán câu hỏi nên được làm rõ.
maiki

OP luôn muốn loại bỏ (trao đổi) các ntừ đầu tiên trong lệnh, n = 1trong ví dụ đầu tiên và n = 2trong ví dụ thứ hai. Câu trả lời của jjlin cho thấy cách xóa từ đầu tiên (và bằng cách áp dụng lại phím tắt, xóa tối đa ntừ). Câu trả lời của bạn liệt kê một vài phím tắt Bash (thực sự hữu ích), nhưng không có cách nào trong số chúng là cách hiệu quả để xóa những ntừ đầu tiên .
slhck

Hm, đọc một lần nữa, các $_tham số có thể sẽ làm việc nếu chỉ có một đối số (ví dụ: nếu n = m - 1nơi mlà tổng số các đối số). Phần còn lại của các phím tắt là không liên quan đến câu hỏi mặc dù.
slhck

@slhck Để tranh luận, tôi đã đọc ví dụ đầu tiên là "thay thế từ thứ 2" :-)
maiki

8

Nếu bạn thành thạo vi, bạn có thể kích hoạt các ràng buộc vi trong bash (hầu hết các shell?) Bằng cách sử dụng lệnh set -o vi. Sau đó, bạn có thể sử dụng các phím vi bình thường để chỉnh sửa lệnh của mình. Trong ví dụ đầu tiên của bạn, bạn có thể làm ^wcwđể xóa "diff", sau đó thay đổi nó thành thanh toán.

Có thể không đáng để học các phím bấm vi chỉ để chỉnh sửa dòng lệnh, nhưng nếu bạn đã biết chúng thì đó là một công cụ tăng năng suất gọn gàng.


Tôi đã học được trên kornshell, đó set -o vilà cách tôi sống! Tôi thậm chí còn làm điều này trong lời nhắc bash của tôi quá.
bgStack15

bindkey -vcho zsh. Esc 0 c w
dùng530873

6

Có rất nhiều cách để da mèo này!

Để thay thế một chuỗi cụ thể, ^old^new^extrasẽ nắm quyền chỉ huy trước đây của bạn, thay thế oldvới new, và append extra. Bạn có thể dừng lại sớm như bạn muốn; ví dụ ^oldsẽ thay thế oldbằng chuỗi rỗng và nối thêm chuỗi trống (về cơ bản là xóa oldvà không làm gì thêm).

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

Biến thể đặc biệt hữu ích của điều này:

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

Để thay thế một từ cụ thể, bạn có thể sử dụng !m:n-pđể chỉ các từ nthông qua plệnh m(sử dụng số âm để đếm ngược từ lệnh hiện tại). Bạn có thể bỏ qua -pphần để chỉ một từ và bỏ qua :m-pphần đó để chỉ toàn bộ lệnh. Các hình thức đặc biệt !!cho !-1, !$cho từ cuối cùng của lệnh trước và !*cho các đối số (tất cả trừ từ 0) của lệnh trước đó là khá tiện dụng.

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

Tôi thường sử dụng cả hai thứ này; zsh đặc biệt tốt ở đây, vì việc nhấn tab sẽ mở rộng các công cụ khó hiểu để đảm bảo bạn hiểu đúng.

Cũng có rất nhiều cách để làm điều này với chỉnh sửa dòng. Đọc trên keybindings của vỏ của bạn.


-2

Hầu hết các chương trình thiết bị đầu cuối đều hỗ trợ ...

  • Nhấn <Up-Arrow>khi cần để hiển thị lại một trong các dòng lệnh trước đó từ lịch sử.
    • Nhấn <Down-Arrow>khi cần thiết để di chuyển về phía trước thông qua danh sách lịch sử.
  • Nhấn <Left-Arrow>khi cần thiết để di chuyển con trỏ đến cuối từ thứ hai.
  • Nhấn <Backspace>khi cần để xóa từ thứ hai.
  • Nhập từ thay thế thứ hai.
    • Nhấn <Right-Arrow>/ <Left-Arrow>khi cần thiết để định vị lại cho nhiều thay đổi.
  • Nhấn <RETURN>để thực hiện lệnh

Nếu dòng lệnh bạn muốn không gần đây, hãy thực hiện tìm kiếm ngược lại <Ctrl-r>như được mô tả trong câu hỏi ...
Có cách nào sử dụng ctrl-r sau khi nhập một phần của lệnh trong bash không?
Sau đó chỉnh sửa thông qua các phím mũi tên khi cần thiết.


-3

Những gì tôi làm (Ubuntu / bash):

1) Arrow uphey để trả về lệnh
2) trước đó Homeđể trở về đầu
3) Sửa đổi lệnh khi cần.

Chống ngốc và đặc biệt hữu ích cho các lệnh nhiều dòng.

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.