Tìm kiếm và thay thế bằng vim trong các dòng cụ thể


94

tôi có thể sử dụng

:5,12s/foo/bar/g

để tìm kiếm foovà thay thế nó bằng bargiữa dòng 5 và 12. Làm cách nào tôi có thể thực hiện điều đó chỉ ở dòng 5 và 12 (chứ không phải ở các dòng ở giữa)?

Câu trả lời:


75

Vim có các nguyên tử biểu thức chính quy đặc biệt khớp trong các dòng, cột nhất định, v.v.; bạn có thể sử dụng chúng (có thể ngoài phạm vi) để giới hạn các kết quả phù hợp:

:5,12s/\(\%5l\|\%12l\)foo/bar/g

Xem :help /\%l


8
Một cách phức tạp hơn tôi mong đợi nhưng trả lời câu hỏi của tôi một cách hoàn hảo. Cảm ơn!
pfnuesel

55

Bạn có thể thực hiện thay thế ở dòng 5 và lặp lại nó với nỗ lực tối thiểu ở dòng 12:

:5s/foo/bar
:12&

Như Ingo đã chỉ ra, hãy :&quên cờ của bạn. Vì bạn đang sử dụng /g, lệnh chính xác sẽ là :&&:

:5s/foo/bar/g
:12&&

Xem :help :&và bạn bè.


10
+1 :&để sử dụng điều tối nghĩa . Nếu có cờ ( s/../../g), người ta phải sử dụng :&&, mặc dù ...
Ingo Karkat

10
@IngoKarkat, phải công bằng, tôi nghĩ \(\%5l\|\%12l\)là tối nghĩa hơn:&
doubleDown

13

Bạn luôn có thể thêm một cvào cuối. Điều này sẽ yêu cầu xác nhận cho mỗi và mọi trận đấu.

:5,12s/foo/bar/gc

1
Đây có thể là một cơn ác mộng nếu có nhiều trận đấu ở giữa dòng 5 và 12 (hãy nhớ rằng có một glá cờ đang diễn ra)
doubleDown

1
@doubleDown Đây không phải là một giải pháp phổ biến (trong đó có nhiều ứng cử viên khả thi), nhưng trong hầu hết các trường hợp, bạn có thực sự thấy rằng việc nhấn n5 hoặc 6 lần có khó hơn việc thêm \(\%5l\|\%12l\)vào câu lệnh thay thế?
Dean

Tôi thấy điều này hữu ích, tôi muốn thay đổi mọi dòng khác, điều này sẽ nhanh hơn những gì tôi đã làm.
tiktak

8

Câu hỏi thú vị. Có vẻ như chỉ có lựa chọn phạm vi và không có lựa chọn nhiều dòng:

http://vim.wikia.com/wiki/Ranges

Tuy nhiên, nếu bạn có điều gì đó đặc biệt ở dòng 5 và 12, bạn có thể sử dụng :gtoán tử. Nếu tệp của bạn trông giống như thế này (số chỉ để tham khảo):

 1     line one
 2     line one
 3     line one
 4     line one
 5     enil one
 6     line one
 7     line one
 8     line one
 9     line one
10     line one
11     line one
12     enil one

Và bạn muốn thay thế onebằng enotrên các dòng có enilthay vì line:

:g/enil/s/one/eno/

5
điều này thực sự được giả định rất nhiều
doubleDown

1

Bạn có thể sử dụng ed- một trình soạn thảo văn bản hướng dòng với các lệnh tương tự như vi và vim. Nó có lẽ có trước vi và vim.

Trong một tập lệnh (sử dụng tài liệu tại đây xử lý đầu vào cho đến khi đánh dấu EndCommand), nó sẽ giống như sau:

ed file <<EndCommands
    5
    s/foo/bar/g
    7
    s/foo/bar/g
    wq
EndCommands

Rõ ràng, các lệnh ed cũng có thể được sử dụng trên dòng lệnh.


3
Tôi không thấy có lợi thế hơn so với giải vimpháp thay thế.
Bernhard

1
Và điều tương tự cũng có thể được thực hiện với Vim; các con số thực sự có thể được đặt trước :s, nhưng vẫn có sự trùng lặp của :slệnh (mà giải pháp của romainl tránh được).
Ingo Karkat

Quan điểm của tôi là người dùng có thể muốn chọn nhiều hơn hai dòng để chỉnh sửa. Trong trường hợp đó, một cách tiếp cận không tương tác có thể được quan tâm - điều mà AFAIK không thể thực hiện được với vim.
suspectus

1
Ồ, Vim có thể làm điều đó (ví dụ: ở chế độ "Ex"), nhưng bạn nói đúng rằng một công cụ khác nên được ưu tiên hơn một trình soạn thảo tương tác. Sở thích của tôi sẽ là sed, mặc dù ...
Ingo Karkat
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.