2010-06-19 23 views
13

Tôi đã thấy các câu hỏi khác liên quan đến việc tìm kiếm sự xuất hiện thứ n của từ/mẫu, nhưng tôi không thể tìm ra cách bạn thực sự thay thế sự xuất hiện thứ n của một mô hình trong vim. Có cách rõ ràng để mã hóa tất cả các lần xuất hiện nhưThay thế sự xuất hiện thứ n của một từ trong vim

:s/.*\(word\).*\(word\).*\(word\).*/.*\1.*\2.*newWord.*/g 

Có cách nào tốt hơn để thực hiện việc này không?

+0

Dường như có trong sed, nhưng không phải là vim 's ///': http://vim.1045645.n5.nabble.com/replace-nth-occurrence-on-each-line-like- sed-td1169460.html – keflavich

Trả lời

4

Bạn có thể làm điều này một chút đơn giản hơn bằng cách sử dụng nhiều tìm kiếm. Mẫu trống trong lệnh :s/pattern/repl/ có nghĩa là thay thế kết quả tìm kiếm gần đây nhất.

:/word//word//word/ s//newWord/ 
or 
:/word//word/ s/word/newWord/ 

Sau đó, bạn có thể lặp lại điều này nhiều lần bằng cách làm @:, hoặc thậm chí [email protected]: để lặp lại lệnh hơn 10 lần.

Ngoài ra, nếu tôi đã làm điều này một cách tương tác tôi sẽ làm một cái gì đó như:

3/word 
:s//newWord/r 

Điều đó sẽ tìm thấy sự xuất hiện thứ ba của từ bắt đầu từ con trỏ và sau đó thực hiện quyền thay người.

+0

Hrm, vẫn còn một số vấn đề với điều này, nếu từ đầu tiên là từ chúng tôi đang tìm kiếm, '3/từ 'sẽ đưa chúng ta đến lần xuất hiện thứ tư. Ngoài ra, khi tôi thử thay thế sau khi tìm thấy thể hiện thứ n, nó vẫn thay thế sự xuất hiện đầu tiên. –

+0

Rất tiếc, có, ': s' cần cờ' r'. –

+0

'3/word' sẽ tìm thấy lần xuất hiện thứ ba bắt đầu từ con trỏ. Chuyển đến đầu tệp bằng 'gg' nếu bạn muốn bắt đầu ở đó. Lưu ý rằng '3/word' tương đương với việc gõ'/word' ba lần để nó chắc chắn tìm thấy sự xuất hiện thứ ba. –

0

Vâng, nếu bạn làm /gc sau đó bạn có thể đếm số lần nó sẽ yêu cầu bạn xác nhận, và đi về phía trước với sự thay thế khi bạn nhận được để các thứ n: D

+0

Yup, nhưng tôi muốn thay thế lần xuất hiện thứ n mà không cần xác nhận (như thể tôi phải viết kịch bản để làm điều đó). –

+4

nó sẽ là một nỗi đau nếu bạn muốn thay thế sự xuất hiện thứ 100 theo cách của bạn ... –

8

Để biết thông tin,

s/\%(\(pattern\).\{-}\)\{41}\zs\1/2/ 

còn có tác dụng thay thế xảy ra 42th. Tuy nhiên, tôi thích the solution given by John Kugelman đơn giản hơn - ngay cả khi nó sẽ không tự giới hạn ở dòng hiện tại.

+0

@ Luc Hermitte: bạn có thể vui lòng cho tôi biết '%' có nghĩa là gì trong câu trả lời của bạn không. Có vẻ như đó là một nhà điều hành mà VIM không thể nhận ra. –

+2

Nó giống như '\ (', nhưng nó nói không ràng buộc những gì được kết hợp bởi dấu ngoặc đơn đến '\ 1'. Xem': h/\% (', IIRC –

1

Điều này trả lời câu hỏi thực tế của bạn, nhưng không phải là ý định của bạn.

Bạn đã hỏi về việc thay thế lần xuất hiện thứ n của một từ (nhưng dường như có nghĩa là "trong một dòng"). Đây là câu trả lời cho câu hỏi như được hỏi, trong trường hợp ai đó tìm thấy câu hỏi như tôi đã làm =)

Đối với các tác vụ lạ (như thay thế mọi lần xuất hiện lần thứ 12 của "chó" bằng "con vẹt"), tôi thích sử dụng các bản ghi đệ quy .

Đầu trống ghi trong @q

qqq 

Bây giờ bắt đầu việc ghi mới trong q

qq 

Tiếp theo, tay làm điều bạn muốn làm (sử dụng ví dụ trên, thay thế Lần xuất hiện thứ 12 của "con chó" với "con vẹt"):

/dog 
nnnnnnnnnnn 

xóa "con chó" và nhập vào số

diwi 

loại vẹt

parrot 

Bây giờ chơi hiện đang trống "@q" bạn ghi

@q 

mà không làm gì.

Cuối cùng, dừng ghi:

q 

Bây giờ ghi hình của bạn trong @q tự gọi mình ở cuối. Nhưng bởi vì nó gọi ghi âm theo tên, nó sẽ không còn trống nữa. Vì vậy, hãy gọi bản ghi:

@q 

Nó sẽ phát lại bản ghi, sau đó ở cuối, làm bước cuối cùng, tự phát lại. Nó sẽ lặp lại điều này cho đến khi kết thúc tập tin.

TLDR;

qq 
q 
/dog 
nnnnnnnnnnndiwiparrot<esc> 
@q 
q 
@q 
2

Thay thế mỗi N thứ xảy ra PATTERN trong một phù hợp với REPLACE.

:%s/\(\zsPATTERN.\{-}\)\{N}/REPLACE/ 
Các vấn đề liên quan