Làm cách nào để lặp lại một chỉnh sửa trên nhiều dòng trong Vim?


122

Tôi biết rằng trong Vim, tôi thường có thể lặp lại một lệnh bằng cách chỉ cần thêm một số vào trước nó. Ví dụ: người ta có thể xóa 5 dòng bằng cách:

5dd

Ví dụ, bạn cũng có thể chỉ định một loạt các dòng để áp dụng một lệnh

:10,20s:hello:goodbye:gc

Làm cách nào để thực hiện 'chỉnh sửa theo chiều dọc'? Ví dụ, tôi muốn chèn một biểu tượng cụ thể, nói một dấu phẩy, tại chỗ ăn xin (bỏ qua khoảng trắng, tức là những gì bạn sẽ nhận được nếu bạn nhập dấu phẩy sau Shift-I trong chế độ lệnh) của mọi dòng trong một phạm vi. Làm thế nào để có thể đạt được điều này (mà không cần sử dụng đến giai đoạn cuối-kỳ-xuống-kỳ-xuống-kỳ)?

Câu trả lời:


107

:10,20s/^/,/

Hoặc sử dụng macro, ghi lại với:

q a i , ESC j h q

dùng với:

@ a

Giải thích: q abắt đầu ghi macro để đăng ký a, qkết thúc ghi. Có đăng ký ađể zcó sẵn cho điều này.


Cảm ơn. Điều gì sẽ xảy ra nếu tôi muốn tương đương với shift-i? Đó là, bỏ qua khoảng trắng ban đầu?
saffsd 10/12/08

2
Giải thích: ^\(\s*\)nắm bắt khoảng trắng ban đầu và lưu nó vào một thanh ghi, sau đó bạn có thể đọc với nó \1.
Svante

136

Ctrl- vvào chế độ trực quan theo khối. Sau đó, bạn có thể di chuyển (theo hjklchiều kim, như bình thường) và nếu bạn muốn chèn nội dung nào đó trên nhiều dòng, hãy sử dụng Shift- i.

Vì vậy, đối với văn bản:

abc123abc
def456def
ghi789ghi

nếu bạn nhấn Ctrl- vvới con trỏ qua 1, nhấn jhai lần để đi xuống hai cột, thì Shift- i,ESC, văn bản của bạn sẽ trông như thế này:

abc,123abc
def,456def
ghi,789ghi

(chèn nhiều dòng có một chút độ trễ và sẽ không hiển thị cho đến SAU KHI bạn nhấn ESC).


3
Đẹp. Ctrl-V có nghĩa là chữ hoa, nhân tiện, bạn có thể nói Ctrl-Shift-v
Svante 10/12/08

8
trên thực tế, đó là CTRL-v hoặc CTRL-V. Vim không phân biệt chữ hoa chữ thường đối với mã CTRL (xem: trợ giúp CTRL- {char}).
rapter

2
sau khi tìm kiếm một chút lý do tại sao phương pháp này không hoạt động là vì nó sử dụng chữ I (shift-i) thay vì i (ngoài ra, nó chỉ là ctrl-v, vì ctrl-shift-v đã chuyển tôi đến cuối)
Willyfrog

4
Tôi tò mò. Tại sao họ không sử dụng imà không có phím shift?
off99555

1
i mà không có shift là chèn ở vị trí hiện tại. shift + i đang chèn ở đầu dòng
Kevin P


44

Nếu bạn đang sử dụng dấu '.' lặp lại lệnh cuối cùng của bạn rất nhiều, sau đó tôi thấy đây là giải pháp thuận tiện nhất cho đến nay. Nó cho phép bạn lặp lại lệnh cuối cùng của mình trên mỗi dòng của khối trực quan bằng cách sử dụng

" allow the . to execute once for each line of a visual selection
vnoremap . :normal .<CR>

1
Điều này hữu ích nhưng cũng bị hạn chế vì .dòng hoạt động khôn ngoan ở chế độ trực quan. Tôi nghĩ rằng chế độ trực quan trong trường hợp này đôi khi có thể thuận tiện để chọn một dải dòng. Nhưng các lệnh và macro linh hoạt và mạnh mẽ hơn trong trường hợp này.
Bohr

23

Tôi tin rằng cách dễ nhất để làm điều này là

1) ghi macro cho một dòng, gọi nó là 'a'; trong trường hợp này một loại

qa I, ESC jq

2) chọn khối dòng mà bạn muốn áp dụng macro

3) sử dụng hàm 'chuẩn' để thực thi macro 'a' trên khối dòng này, tức là,

:'<,'>norm@a

17

Tôi nghĩ đơn giản nhất là ghi lại một macro, sau đó lặp lại macro bao nhiêu lần tùy thích. Ví dụ: để thêm dấu phẩy ở đầu mỗi dòng, bạn gõ:

q a I , ESC j q

để lặp lại 5 lần, bạn nhập

5 @ a


2

Với chỉnh sửa của bạn đã được lưu trong .toán tử, hãy làm như sau:

  1. Chọn văn bản bạn muốn áp dụng toán tử để sử dụng chế độ trực quan
  2. Sau đó chạy lệnh :norm .

1

Ngoài các macro, như đã được trả lời, đối với trường hợp cụ thể là chèn dấu phẩy trong một dải dòng (ví dụ từ dòng 10 đến dòng 20), bạn có thể làm như sau:

:10,20s/\(.*\)/,\1

Nghĩa là, bạn có thể tạo một đối sánh nhóm được đánh số bằng \ (và \) và sử dụng \ 1 trong chuỗi thay thế để nói "thay thế bằng nội dung của đối sánh".

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.