Vim: chèn cùng một ký tự trên nhiều dòng


306

Đôi khi tôi muốn chỉnh sửa một khối văn bản trực quan nhất định trên nhiều dòng.

Ví dụ, tôi sẽ lấy một văn bản trông như thế này:

name
comment
phone
email

Và làm cho nó trông như thế này

vendor_name
vendor_comment
vendor_phone
vendor_email

Hiện tại cách tôi sẽ làm bây giờ là ...

  1. Chọn tất cả 4 dòng hàng của một khối bằng cách nhấn Vvà sau đó jbốn lần.
  2. Thụt với >.
  3. Quay lại một chữ với h.
  4. Tới khối chế độ trực quan với Ctrlv.
  5. Chọn bốn hàng bằng cách nhấn jbốn lần. Tại thời điểm này, bạn đã chọn một khối hình ảnh 4x1 của khoảng trắng (bốn hàng và một cột).
  6. Nhấn C. Lưu ý điều này khá nhiều thụt vào bên trái bởi một cột.
  7. Nhập ra " vendor_"mà không có trích dẫn. Để ý không gian thừa chúng tôi phải đặt lại.
  8. Nhấn Esc. Đây là một trong số rất ít lần tôi sử dụng Escđể thoát khỏi chế độ chèn. Ctrlcsẽ chỉ chỉnh sửa dòng đầu tiên.
  9. Lặp lại bước 1.
  10. Thụt đường khác với <.

Tôi không cần thụt lề nếu có ít nhất một cột khoảng trắng trước các từ. Tôi sẽ không cần khoảng trắng nếu tôi không phải xóa khối hình ảnh c.

Nhưng nếu tôi phải xóa, vậy có cách nào để thực hiện những gì tôi đã thực hiện ở trên mà không tạo khoảng trắng cần thiết với thụt lề không?

Ngoài ra, tại sao chỉnh sửa nhiều dòng cùng một lúc chỉ hoạt động bằng cách thoát khỏi chế độ chèn với Eschơn Ctrlc?


Đây là một ví dụ phức tạp hơn:

name    = models.CharField( max_length = 135 )
comment = models.TextField( blank = True )
phone   = models.CharField( max_length = 135, blank = True )
email   = models.EmailField( blank = True )

đến

name    = models.whatever.CharField( max_length = 135 )
comment = models.whatever.TextField( blank = True )
phone   = models.whatever.CharField( max_length = 135, blank = True )
email   = models.whatever.EmailField( blank = True )

Trong ví dụ này, tôi sẽ thực hiện khối hình ảnh dọc trên ., và sau đó lắp lại nó trong chế độ chèn, tức là, gõ .whatever.. Hy vọng bây giờ bạn có thể thấy nhược điểm của phương pháp này. Tôi bị giới hạn chỉ chọn một cột văn bản hoàn toàn giống nhau ở vị trí thẳng đứng .


9
Cách tốt hơn: ":% s / ^ / eller_ /"
Paul Tomblin

1
Cảm ơn vì sự trả lời. Điều đó hoạt động nếu tôi chỉ muốn thêm một từ vào mỗi dòng. Nhưng phương pháp tôi sử dụng có thể được thực hiện ở bất kỳ vị trí nào. Hãy để tôi thêm một ví dụ khác của tôi với một ví dụ phức tạp hơn.
hobbes3

3
Sau đó làm nổi bật các dòng bạn muốn thay đổi bằng shift-V và nhập lệnh tìm kiếm và thay thế phù hợp - trong ví dụ thứ hai,:s/models\./\0whatever./
Paul Tomblin

Nhiều cách để đạt được những điều trên. Để trả lời đầy đủ tất cả các phần của câu hỏi sau đó phần 1) hoặc chế độ trực quan hoặc chế độ trực quan, tôi chỉnh sửa esc hoạt động độc đáo như được cung cấp trong câu trả lời (tôi thích lựa chọn trực quan hơn trong GVIM). Đối với phần 2), macro có lẽ dễ nhất như được cung cấp bởi Brian Neal. Tài nguyên tốt nhất mà tôi biết về tất cả các loại "cách làm" này là Vim thực tế của Drew Neil. Tuyệt vời đọc nhanh và tham khảo trọng lượng nhẹ bất cứ khi nào bạn quên một công thức. Hy vọng đề xuất này sẽ giúp được ai đó, nó sẽ rất xứng đáng với nỗ lực của nhiều người dùng vim.
arcseldon

@Paul: Và nếu bạn đang đếm tổ hợp phím , bạn có thể thay thế \0bằng &.
icktoofay

Câu trả lời:


912
  1. Di chuyển con trỏ đến ntrong name.
  2. Vào chế độ khối trực quan ( Ctrlv).
  3. Nhấn jba lần (hoặc 3j).
  4. Báo chí I(vốn i).
  5. Nhập vào vendor_. Lưu ý: Nó sẽ chỉ cập nhật màn hình ở dòng đầu tiên - cho đến khi Escđược nhấn (6.), tại đó tất cả các dòng sẽ được cập nhật.
  6. Nhấn Esc.

mini-screencast trình diễn phương pháp

IPhải sử dụng chữ hoa thay vì chữ thường i, vì chữ thường iđược hiểu là bắt đầu của một đối tượng văn bản , nó khá hữu ích, ví dụ như để chọn bên trong một khối thẻ ( it):

mini-screencast cho thấy tính hữu dụng của đối tượng văn bản 'nó'


12
Tôi không thể làm điều này hoạt động trong Windows (vì CTRL + V được ánh xạ để dán clipboard). Nhưng Vim cũng đã ánh xạ nó tới Ctrl + Q cho phiên bản Windows.
Arnestig

2
@Ven: Vim không thực sự bận rộn trong thời gian đó. Nó chỉ chờ bạn nhấn một phím khác và cuối cùng là hết giờ. Hai thử nghiệm cho bạn: đầu tiên, hãy thử nhấn thoát và sau đó nhấn ngay một phím khác, như jhoặc ^L. Rốt cuộc bạn sẽ thấy Vim không bận rộn; nó chỉ chờ đợi Thứ hai, hãy thử thay đổi 'timeout'thành giá trị thấp hơn, như 80(thay vì mặc định 1000) và quan sát rằng nó sẽ hết nhanh hơn.
icktoofay

1
@icktoofay Có vẻ như biến bạn muốn đặt là timeoutlenkhông timeout.
Jez

4
@ANjaNA: Nếu nơi bạn muốn chèn là tất cả trong cùng một cột (ví dụ: nếu các số có cùng độ dài), bạn có thể sử dụng cùng một kỹ thuật ngoại trừ nhấn Athay vì I, sẽ chèn sau khối đã chọn thay vì trước đó. Tuy nhiên, nếu các dòng của bạn có độ dài khác nhau, điều đó sẽ không hoạt động; Tôi thích sử dụng một sự thay thế phù hợp với phần cuối của mỗi dòng cho điều đó, ví dụ như chọn một số dòng và sử dụng :s/$/inserted/.
icktoofay

3
Tôi đã phải nhấn mũi tên xuống sau khi nhấn esc để làm việc này
GeoSword

69

Một cách tiếp cận khác là sử dụng lệnh .( dot) kết hợp với I.

  1. Di chuyển con trỏ đến nơi bạn muốn bắt đầu
  2. nhấn I
  3. Nhập tiền tố bạn muốn (ví dụ: vendor_ )
  4. nhấn esc.
  5. nhấn j để đi xuống một dòng
  6. Kiểu . để lặp lại chỉnh sửa cuối cùng, tự động chèn lại tiền tố
  7. Thay thế nhanh chóng giữa j.

Tôi thấy kỹ thuật này thường nhanh hơn chế độ khối trực quan đối với số lượng bổ sung nhỏ và có thêm lợi ích là nếu bạn không cần phải chèn văn bản trên mỗi dòng trong một phạm vi, bạn có thể dễ dàng bỏ qua chúng bằng cách nhấn thêm j 's .

Lưu ý rằng đối với số lượng lớn các bổ sung liền kề, cách tiếp cận khối hoặc macro có thể sẽ vượt trội hơn.


Rất vui khi thấy một cách tiếp cận khác.
Ibn Saeed

Tôi thích điều này chỉ cho một vài dòng. Dễ dàng hơn nhiều để thực hiện IMO.
Dan Bechard

Sau khi bạn nhập tiền tố bạn muốn, bạn không cần nhấn phím thoát?
iamnotsam

41
  1. Chọn các dòng bạn muốn sửa đổi bằng cách sử dụng CtrlV.
  2. Nhấn:

    • I: Chèn trước những gì đã chọn.
    • A: Nối sau những gì đã chọn.
    • c: Thay thế những gì đã chọn.
  3. Nhập văn bản mới.

  4. Nhấn Escđể áp dụng các thay đổi cho tất cả các dòng được chọn.

4
Thông minh! Tôi chỉ nêu bật bước cuối cùng Esccho các noobs VIM như mình - tôi phải mất một thời gian để nhận ra rằng những thay đổi sẽ được lan truyền "sau này"!
Bọ Bunny

1
Thật tuyệt, không biết về các tùy chọn "A" và "C".
hobbes3

Tại sao điều này không làm việc v? Tôi có thể làm điều đó với Ctrl+V --> A, nhưng thực hiện vđể chọn văn bản không hoạt động - Achỉ gắn vào dòng đó. Cả hai đều không chọn sao? Ngoài ra, rất lạ - Achỉ nối vào cuối dòng NẾU tôi mở rộng khối hình ảnh đến cuối dòng; mặt khác, nó xuất hiện bất cứ nơi nào khối hình ảnh kết thúc cho mỗi dòng. Nó giống như nó không nhận ra một sự khác biệt giữa aA.
Alex G

1
Tôi cần phải sử dụng cthay vì C, nhưng nó hoạt động hoàn toàn tốt. Cảm ơn bạn
Tarol

29

Tôi sẽ sử dụng một macro để ghi lại hành động của mình và sau đó sẽ lặp lại nó.

  1. Đặt con trỏ của bạn vào chữ cái đầu tiên trong tên .
  2. Nhấn qqđể bắt đầu ghi vào bộ đệm q.
  3. Nhấn iđể chuyển sang chế độ chèn, nhập vector_ , rồi nhấn Escđể thoát khỏi chế độ chèn.
  4. Bây giờ nhấn 0để quay trở lại đầu dòng.
  5. Bây giờ đánh jđể đi xuống.
  6. Bây giờ nhấn qmột lần nữa để dừng ghi âm.

Bây giờ bạn có một macro tốt đẹp.

Nhập 3@qđể thực hiện macro của bạn ba lần để thực hiện phần còn lại của dòng.


"Q" có đặc biệt không (đối với "macro nhanh"?)?
Peter Mortensen

Làm thế nào để macro có thể được thực hiện liên tục (làm việc qua nhiều phiên)?
Peter Mortensen

@PeterMortensen Vim có một tính năng được gọi là phiên sẽ duy trì bộ đệm (và rất nhiều thứ khác) mà bạn có thể xem xét.
Brian Neal

27
:%s/^/vendor_/

hoặc tôi đang thiếu một cái gì đó?


Bạn đang thiếu thực tế rằng đó có thể là một ẩn ý trong một tệp có nhiều dòng khác mà vender_tiền tố không mong muốn.
Dan Bechard

9
@ Dan Nếu chỉ có một ẩn ý là cần thiết, bạn có thể giới hạn việc tìm kiếm một tập hợp các số dòng, ví dụ:1,4s/^/vendor_/
Brad Koch

1
@BradKoch Thú vị. Tôi đã không nhận thức được các hạn chế số dòng, cảm ơn vì điều đó.
Dan Bechard

8
thật thú vị, nhưng những gì thực tế hơn là chặn trực quan chọn Vvà gõ :. Nó sẽ thêm tiền tố vào biểu thức ed :'<,'>mà làm cho ed chỉ áp dụng cho lựa chọn với:'<,'>s/^/vendor_/
Dolanor

12

Cập nhật tháng 1 năm 2016

Mặc dù câu trả lời được chấp nhận là một giải pháp tuyệt vời, nhưng đây thực sự là một tổ hợp phím ít hơn một chút và có tỷ lệ tốt hơn - dựa trên nguyên tắc dựa trên câu trả lời được chấp nhận.

  1. Di chuyển con trỏ đến ntrong name.
  2. Vào chế độ khối trực quan ( ctrlv).
  3. nhấn 3j
  4. Nhấn I.
  5. Nhập vào vendor_.
  6. Nhấn esc.

minh họa trực quan

Lưu ý, điều này có ít tổ hợp phím hơn so với câu trả lời được chấp nhận được cung cấp (so sánh Bước 3). Chúng tôi chỉ đếm số lượng hành động j để thực hiện.

Nếu bạn đã bật số dòng (như minh họa ở trên) và biết số dòng bạn muốn chuyển đến, thì bước 3 có thể được thay đổi thành # Gtrong đó # là số dòng mong muốn.

Trong ví dụ của chúng tôi ở trên, điều này sẽ được 4G. Tuy nhiên, khi xử lý chỉ với một vài số dòng, số lượng rõ ràng hoạt động tốt.


7

Tôi muốn bình luận rất nhiều dòng trong một số tệp cấu hình trên một máy chủ chỉ có vi (không có nano), vì vậy phương pháp trực quan cũng cồng kềnh. Đây là cách tôi đã làm điều đó.

  1. Mở tập tin vi file
  2. Hiển thị số dòng :set number!hoặc:set number
  3. Sau đó sử dụng số dòng để thay thế bắt đầu bằng "#", làm thế nào?

:35,77s/^/#/

Lưu ý: các số đã bao gồm, các dòng từ 35 đến 77, cả hai sẽ được sửa đổi.

Để bỏ ghi chú / hoàn tác điều đó, chỉ cần sử dụng :35,77s/^#//

Nếu bạn muốn thêm một từ văn bản dưới dạng một nhận xét sau mỗi dòng mã, bạn cũng có thể sử dụng:

:35,77s/$/#test/ (đối với các ngôn ngữ như Python)

:35,77s/;$/;\/\/test/ (đối với các ngôn ngữ như Java)

tín dụng / tài liệu tham khảo:

  1. /unix/84929/uncommenting-multipl-lines-of-code-specified-by-line-numbers-USE-vi-or-vim

  2. /unix/120615/how-to-comment-multipl-lines-at-once


Đây là giải pháp hoàn hảo cho tôi vì tôi thường chỉ sử dụng vim-tiny.
JSON C11

7

Bạn cũng có thể có một trường hợp sử dụng mà bạn muốn xóa một khối văn bản và thay thế nó.

Như thế này

Hello World

Hello World

Đến

Hello Cool

Hello Cool

Bạn chỉ có thể chọn khối trực quan chọn "Thế giới" trong cả hai dòng.

Nhập cđể thay đổi - bây giờ bạn sẽ ở chế độ chèn.

Chèn những thứ bạn muốn và nhấn thoát.

Cả hai đều được phản ánh theo chiều dọc. Nó hoạt động giống như 'Tôi', ngoại trừ việc nó thay thế khối bằng văn bản mới thay vì chèn nó.


6

Giả sử bạn có tệp này:

something

name
comment
phone
email

something else
and more ...

Bạn muốn thêm "nhà cung cấp_" ở phía trước "tên", "nhận xét", "điện thoại" và "email", bất kể chúng xuất hiện ở đâu trong tệp .

:%s/\<\(name\|comment\|phone\|email\)\>/vendor_\1/gc

Các clá cờ sẽ nhắc bạn để xác nhận. Bạn có thể bỏ nó nếu bạn không muốn lời nhắc.


5

Một thay thế có thể linh hoạt hơn:

Ví dụ: Để nhập văn bản XYZ ở đầu dòng

:%norm IXYZ

Chuyện gì đang xảy ra ở đây vậy?

  • % == Thực thi trên mỗi dòng
  • norm == Thực hiện các phím sau trong chế độ bình thường
  • I == Chèn ở đầu dòng
  • XYZ == Văn bản bạn muốn nhập

Sau đó, bạn nhấn Enter, và nó thực thi.

Cụ thể theo yêu cầu của bạn:

:%norm Ivendor_

Bạn cũng có thể chọn một phạm vi cụ thể:

:2,4norm Ivendor_

Hoặc thực hiện trên một phạm vi hình ảnh đã chọn:

:'<,'>norm Ivendor_

1
có thể gửi các chuỗi khóa như <Esc> trong khi ở chế độ chèn (định mức Iabc <ESC>) để thực hiện nhiều nội dung thú vị hơn không?
batbrat

1
@batbrat Mình mới tìm ra điều này! Bạn có thể nhấn ctrl-v ctrl-[để chèn "Esc thoát", kéo bạn trở lại "chế độ bình thường" cho mục đích của lệnh thông thường của bạn. Tôi chỉ thử nghiệm này với '<,'>norm Iaa^[ysiw", nơi ^[là thoát Esc.
Aubrey Lavigne

4
Use Ctrl+V to enter visual block mode
Move Up/Down to select the columns of text in the lines you want to comment.
Then hit Shift+i and type the text you want to insert.
Then hit Esc, wait 1 second and the inserted text will appear on every line

phương pháp này có hoạt động cho tất cả các phiên bản của vim hoặc yêu cầu bất kỳ plugin vim nào không? lý do tại sao tôi hỏi là vì đôi khi nó hoạt động trên một số máy, nhưng đôi khi không. tôi không thể tìm ra sự khác biệt vim đi kèm với git trên windows - tôi không thể làm cho nó hoạt động được. trên một số máy linux Ubuntu và centos, tôi không thể làm cho nó hoạt động được. tôi đã thành công trong một vài trường hợp hiếm hoi, nhưng tôi không thể tái tạo thành công. đó là một bí ẩn dường như không có gì xảy ra sau khi tôi nhấn ESC.
davidj411

Thật kỳ lạ, nó làm việc cho tôi bây giờ. không có gì thay đổi, ngoại trừ các ngôi sao :) trong khi tìm kiếm giải pháp cho vấn đề của mình, tôi đã tìm thấy thứ gì đó ở trang này mặc dù có đề cập đến thứ gì đó cần tìm trong vim vim.wikia.com/wiki/Inserting lòng_in_mult Môn_lines Trong Vim, hãy kiểm tra xem bạn có tính năng toán tử khối (I, A và hơn thế nữa) bằng cách nhập lệnh: version. Đầu ra phải bao gồm + visualextra.
davidj411

Tôi có nghĩa là để thêm một nhận xét nói chung, không phải câu trả lời của bạn. Hầu hết các câu trả lời này đều nói cùng một điều nhưng sử dụng các từ khác nhau. Của tôi có một cái gì đó khác nhau để cung cấp và bao gồm một liên kết.
davidj411

2
  1. Ctrl + v để chuyển sang chế độ khối trực quan
  2. Chọn các dòng bằng cách sử dụng mũi tên lên và xuống
  3. Nhập chữ thường 3i(nhấn chữ thường I ba lần)
  4. I (báo chí vốn I . Điều đó sẽ đưa bạn vào chế độ chèn.)
  5. Viết văn bản bạn muốn thêm
  6. Esc
  7. Nhấn mũi tên xuố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.