Vim: s thay thế lần xuất hiện N <g đầu tiên trên một dòng


13

Trong vim, đôi khi tôi có dịp thay thế một vài lần xuất hiện đầu tiên của trận đấu trên một dòng, nhưng không phải ai cũng muốn như gvậy. ví dụ:

a a a a a

đến

b b b a a

Tôi biết tôi có thể sử dụng :s/a/b/[enter]:[up][enter]:[up][enter], nhưng điều đó đủ tẻ nhạt ở ba lần lặp lại, tôi có những dòng có khả năng thay thế hơn 10.
Tôi đã thử:

  • :s/a/b/3g: vim phàn nàn về các ký tự dấu.
  • :s/a/b/3: thay đổi lần xuất hiện đầu tiên trên này và hai dòng sau.
  • 3:s/a/b: giông như trươc đo.
  • :s/a/b/g3: thay đổi tất cả các lần xuất hiện trên này và hai dòng tiếp theo.
  • :3s/a/b: thay đổi lần xuất hiện đầu tiên trên dòng 3.
  • :/a/,3/a/s/a/b: thay đổi lần xuất hiện đầu tiên trên mỗi dòng giữa dòng tiếp theo avà dòng thứ ba có atrong tệp (nhắc nhở nếu cần).
  • :/a/,/\([^a]*a\)\{3\}/s/a/b/: thay đổi lần xuất hiện đầu tiên trên mỗi dòng giữa điều này và lần tiếp theo với 3 agiây trên đó (và điều này sẽ không dễ dàng mở rộng cho tìm kiếm nhiều ký tự).

Và nhiều mẫu địa chỉ khác, không có mẫu nào hoạt động. Tôi phải nói rằng, tôi đã học được một lượng khá lớn về :slệnh cố gắng tìm câu trả lời cho vấn đề này, nhưng tôi vẫn chưa giải quyết được.

Bất cứ ai biết làm thế nào để làm điều này?

(điểm thưởng cho phạm vi cụ thể, ví dụ: lần thứ hai đến lần thứ tư)


2
Tôi khá chắc chắn rằng bạn không thể làm điều đó trong vim, nhưng để làm cho nó bớt tẻ nhạt hơn, bạn có biết về "n" và "." ở chế độ trực quan? Đó là, bạn sử dụng / mẫu / để tìm thứ cần thay đổi, thay đổi nó bằng cách sử dụng "cw" hoặc bất cứ điều gì, thn sử dụng "n" (chỉ n, không có dấu ngoặc kép) để tìm mẫu tiếp theo và nhấn "." (chỉ thời gian, không có dấu ngoặc kép) để thực hiện chỉnh sửa cuối cùng.
Bruce Ediger

@BruceEdiger Tôi đã biết n.mặc dù tôi không nghĩ sẽ sử dụng chúng ở đây. Chắc chắn là một sự cải thiện, cảm ơn.
Kevin

s/a/=something/nên làm thủ thuật ( :help sub-replace-=). Tôi không đủ thông thạo Vim để viết somethingngay lập tức.
Gilles 'SO- ngừng trở nên xấu xa'

Lưu ý: :[up][enter]có thể được thay thế bằng &, điều này vẫn không lý tưởng nhưng ít nhất là ít đau đớn hơn.
Cửu Long

Câu trả lời:


10

Dựa trên :s/pattern/replacement/gc ý tưởng từ Samus_ (dường như là cách đơn giản nhất để đảm bảo hoạt động chính xác khi mẫu được chứa trong chuỗi thay thế), để thay thế lần xuất hiện thứ 2 đến thứ 4 trên một dòng:

:call feedkeys("nyyyq") | s/pat/string/gc

feedkeys()là một chức năng nhồi chuỗi đầu vào vào hàng đợi đầu vào bàn phím. Vấn đề là phải thực hiện việc đếm trước để bạn không phải lo lắng về việc mất số đếm hoặc bị gián đoạn.

Đối với trường hợp tổng quát hơn, để thay thế lần xuất hiện từ Mth đến Nth trên một dòng cho N lớn hơn hoặc bằng M rất lớn :

:call feedkeys(repeat("n", M-1) . repeat("y", N-M+1) . "q") | s/pat/string/gc

Thay thế MN bằng các giá trị bạn muốn (thậm chí bạn có thể vimthực hiện số học tinh thần tầm thường nếu bạn không muốn tự làm điều đó). Lưu ý rằng đó .là toán tử nối chuỗi của VimL. Rõ ràng điều này chỉ tiết kiệm tổ hợp phím cho M lớn . Nếu bạn sử dụng chức năng này thường xuyên, nó có thể giúp bạn tiết kiệm thời gian để đặt phần trên vào một lệnh tùy chỉnh hoặc chức năng nào đó, vì nó khá khó để gõ.


Hừm. Tôi thích cái này. Tôi cũng có thể viết một hàm cho nó.
Kevin

8

Đối với câu hỏi đầu tiên tôi sẽ làm:

:s/a/b
&&

Thứ hai là khó hơn, tôi không biết cách tự động làm nhưng bạn có thể khiến vim nhắc bạn trên mỗi trận đấu như thế này:

:s/a/b/gc

Sau đó, bạn trả lời "không" cho n khớp đầu tiên và "có" với những người khác.


Hmm, tôi quên mất c, đó có thể là giải pháp tốt nhất được đề xuất. Tôi vẫn phải tính, nhưng tôi nghĩ đó là tùy chọn đầu tiên sẽ hoạt động với các thay thế có chứa chuỗi tìm kiếm.
Kevin

6
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a
a a a a a

:3,6g/^/let i=0 | while i<3 | s/a/b/ | let i+=1 | endwhile

a a a a a
a a a a a
b b b a a
b b b a a
b b b a a
b b b a a
a a a a a

1
Điều này là tốt, nhưng nó vẫn gặp phải vấn đề mà Gilles đã chỉ ra (trên một bài đăng khác, dường như đã bị xóa), rằng nó chỉ hoạt động nếu thay thế không chứa mẫu. Mặc dù tôi thích ý tưởng kịch bản.
Kevin

Một điều của vẻ đẹp!
giám mục

1

Tôi nghĩ rằng điều này có thể làm việc, thay thế đầu tiên, sau đó lặp lại 2 lần:

:s/a/b/
2@:
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.