Cách sao chép mỗi dòng 11 lần, tăng số 1 cuối cùng trong mỗi dòng từ 2-12


9

Tôi có một số dòng trong một tệp và tôi muốn sao chép mỗi dòng 11 lần (biến mỗi dòng thành 12 dòng) và tăng "1" cuối cùng trong mỗi dòng để 12 dòng có "1" đến " 12 ", trong đó" 1 "ban đầu là. Có thể có các lần xuất hiện khác của "1" trong mỗi dòng, nhưng "1" tôi muốn tăng sẽ luôn là lần xuất hiện cuối cùng trong mỗi dòng. Một cách khác để xem xét đó là "1" cuối cùng luôn nằm sau "/ nt /" - như trong "/ nt / 1" (và nó sẽ luôn là lần xuất hiện duy nhất của "/ nt / 1" trong mỗi dòng) .

Vì vậy, ví dụ, nếu tôi có:

1stlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/1blah
3rdlineblahblahblah/nt/1blah

Tôi muốn biến nó thành:

1stlineblahblahblah/nt/1blah
1stlineblahblahblah/nt/2blah
1stlineblahblahblah/nt/3blah
1stlineblahblahblah/nt/4blah
1stlineblahblahblah/nt/5blah
1stlineblahblahblah/nt/6blah
1stlineblahblahblah/nt/7blah
1stlineblahblahblah/nt/8blah
1stlineblahblahblah/nt/9blah
1stlineblahblahblah/nt/10blah
1stlineblahblahblah/nt/11blah
1stlineblahblahblah/nt/12blah
2ndlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/3blah
...

Trước đây tôi đã tìm thấy lệnh:

:for i in range(0,12) | put ='1stlineblahblahblah/nt/'.i.'blah' | endfor

hoạt động cho mục đích này, nhưng tôi sẽ phải tự chạy lệnh này cho từng dòng và tự nhập từng dòng vào (hoặc sao chép - và dán nó). Có cách nào để lấy các dòng đã có trong tệp và chỉ cần chạy một lệnh biến mỗi dòng thành mười hai, theo cách mà tôi đã mô tả?

Cảm ơn trước cho bất cứ ai có thể giúp tôi với điều này. Tôi cũng chỉ muốn lưu ý rằng đây là câu hỏi thứ hai của tôi ở đây, và tôi rất vui vì đã nhận được một số giải pháp nhanh chóng và hiệu quả cho câu hỏi đầu tiên của tôi, điều mà tôi rất biết ơn.

Câu trả lời:


8

Đây là một sự thay thế giải quyết vấn đề:

:%s/\(.*\)1\(.*\)/\=join(map(range(1, 12), 'submatch(1) . v:val . submatch(2)'), "\n")

Sự thay thế khớp với từng dòng chứa "1" và chụp văn bản trước {c1}và sau {c2}"1" cuối cùng. Đối với mỗi dòng khớp, phạm vi số từ một đến mười hai {n}được ánh xạ để tạo mười hai dòng có dạng {c1}{n}{c2}. Mỗi nhóm mười hai dòng thay thế dòng liên kết ban đầu được liên kết của nó.

Xem :h sub-replace-expression.


2
Wow, lệnh một dòng tuyệt vời. Tôi nhớ rằng bạn cũng tìm thấy một giải pháp một dòng thanh lịch cho câu hỏi đầu tiên tôi đã hỏi vài tuần trước. Công việc rất tốt. Cảm ơn rât nhiều. Ngoài ra, tôi đoán có một cách để đặt cái này vào tệp _vimrc để tôi có thể thực thi một lệnh hoặc hàm dễ nhớ mà không cần gõ toàn bộ dòng trên (hoặc phải cuộn qua danh sách các lệnh trước đó), nhưng Tôi chưa đủ quen thuộc với cú pháp _vimrc để biết cách thực hiện.
couldwasiereisawelba 17/2/2016

10

Bạn có thể làm điều này bằng cách

  1. ghi lại một macro, sau đó
  2. sử dụng globallệnh ex để thực thi số lần macro n cho mỗi dòng trong tệp.

Sau khi ghi macro, hoàn tác các thay đổi được thực hiện trong khi ghi hoặc sẽ có n + 1 dòng bổ sung cho dòng đầu tiên và n cho các dòng liên tiếp.

Ghi lại macro để ađăng ký với

qayyp$?\d<CR><C-A>q

Điều này ghi vào register a( qa...q) lệnh sau:

  • yyp: nhân đôi dòng hiện tại
  • $: di chuyển đến cuối dòng
  • ?\d<CR>: tìm kiếm ngược cho một chữ số
  • <C-A>: chữ số tăng dưới con trỏ thêm một

Khi macro được ghi lại, hãy xóa các thay đổi được thực hiện trong khi ghi lại bằng cách hoàn tác ( uu) hoặc bằng cách xóa dòng hiện tại ( dd). Sau đó lặp lại macro 11(hoặc bất kỳ số lần) nào cho mỗi dòng trong tệp bằng lệnh toàn cầu:

:g//normal 11@a

2
Nó đã làm việc! Rất tuyệt cảm ơn bạn. Ban đầu tôi gặp vấn đề với Ctrl-a làm nổi bật mọi thứ thay vì thêm, bởi vì tôi đang sử dụng gVim trong Windows ... nhưng tôi đã tìm kiếm nhanh và tìm thấy chủ đề này - stackoverflow.com/questions/289681/ trộm - nơi tôi đã sử dụng đề xuất đặt nnoremap <kPlus> <Ca> nnoremap <kMinus> <Cx> vào _vimrc để tôi có thể sử dụng các phím "+" và "-" để thêm và trừ. Ngoài ra, lệnh toàn cầu cần phải là: g // bình thường 11 @ a đối với tôi, nhưng điều đó dễ dàng được tìm ra. Cảm ơn bạn!
couldwasiereisawelba 17/2/2016

6

Hai lối:

Sử dụng một macro!

Bắt đầu với

1stlineblahblahblah/nt/1blah
2ndlineblahblahblah/nt/1blah
3rdlineblahblahblah/nt/1blah

Với con trỏ trên dòng đầu tiên

qqyyp$?\d<CR><Ctrl-a>q
10@q

Mà không:

qq Bắt đầu ghi một macro vào thanh ghi q

yyp kéo dòng hiện tại và dán nó bên dưới

$?\d<CR> Đi đến cuối dòng và tìm chữ số đầu tiên nhìn về phía sau

<Ctrl-a> Tăng số

q Dừng ghi macro.

Điều này để lại cho bạn:

1stlineblahblahblah/nt/1blah
1stlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/2blah
2ndlineblahblahblah/nt/3blah

Với con trỏ trên dòng thứ hai. Chỉ cần lặp lại macro này nhiều lần như mong muốn (Ví dụ: lặp lại mười lần với 10 @ q). Nếu bạn muốn tự động hóa quy trình này cho từng dòng, hãy thực hiện nó trên toàn cầu trên mỗi dòng:

:g//normal 11@q

Ngoài ra, với phiên bản mới hơn của vim: Dán dòng bạn muốn tuy nhiên nhiều lần, khối trực quan chọn chữ số bạn muốn tăng và nhấn g <Ctrl-a>. Điều này sẽ tăng tất cả các số trong khối trực quan như bạn mong muốn. Đây là một quá trình thủ công hơn, tuy nhiên.


1
Tuyệt vời, tôi không biết g <c-a>đường đi. Cám ơn vì đã chia sẻ.
kba đứng với Monica

1
@fruglemonkey Phần đầu tiên trong câu trả lời của bạn giống như phần trên, nhưng dù sao cũng cảm ơn bạn. Phần thứ hai, tôi không nghĩ là phù hợp với mình (trừ khi tôi làm sai điều gì đó), vì vậy tôi không được sử dụng đúng phiên bản.
couldwasiereisawelba 17/2/2016

5

Tôi thấy dễ dàng nhất để sử dụng macro cho các tác vụ một lần như vậy. Chỉ cần bắt đầu ghi một macro với q+ tên của thanh ghi và thực hiện tác vụ một lần. Tôi thấy một nhiệm vụ có thể lặp lại ở đây:

  • Chọn dòng
  • kéo
  • dán (sẽ đưa bạn vào dòng tiếp theo)
  • đi đến cuối dòng
  • quay lại một từ
  • tăng thêm một

Bây giờ ghi lại các tổ hợp phím cần thiết để đăng ký a, ở chế độ bình thường:

qayyp$b<c-a>.

Xóa dòng một lần nữa để kiểm tra xem việc thực thi macro 11 lần có mang lại kết quả đúng cho một dòng hay không:

11@a

Nó làm! Vì vậy, hãy hoàn tác lại và tự động hóa toàn bộ quá trình trong macro thứ hai b:

qb11@aj

Bây giờ bạn có thể thực thi @bcho đến khi kết thúc tệp và nó sẽ tạo ra kết quả đầu ra mà bạn muốn. Nghe có vẻ phức tạp nhưng thực sự không phải là một khi bạn đã quen với các mẫu chỉnh sửa thông thường.


Tôi không chắc mình có làm gì sai không, nhưng dường như nó không hoạt động. Tôi đã làm theo những gì bạn viết, nhưng có lẽ tôi đã hiểu nhầm một cái gì đó hoặc không thực hiện một cái gì đó đúng. (Tôi đang nhận được số đầu tiên của dòng tăng lên, không phải là số cuối cùng của dòng.) Cảm ơn bạn đã trả lời.
couldwasiereisawelba 17/2/2016

3
Tôi nghĩ rằng vĩ mô đầu tiên nên được qaVyp$b<c-a>. Hoặc tốt hơn, chỉ cần qayyp$b<c-a>.
Karl Yngve Lervåg

1
Cảm ơn, @ KarlYngveLervåg, bạn nói đúng, tôi đã sửa macro.
kba đứng với Monica

2
. Argh :( thanks vì đã @ablewasiereisawelba triệt để tôi đoán vĩ mô qqyyp$?\d<CR><Ctrl-a>qbởi @fruglemonkey và @jjaderberg là tốt hơn vì nó tìm kiếm số cuối cùng tôi sẽ thay đổi nó cho đầy đủ..
KBA đứng với Monica

2
@kba Tôi chỉ nghĩ rằng nếu bất cứ ai dành thời gian và nỗ lực để trả lời câu hỏi của tôi, tôi ít nhất có thể thử giải pháp của anh ấy - ngay cả khi tôi đã tìm thấy giải pháp làm việc từ người khác. Tôi đánh giá cao nỗ lực của bạn - và nếu điều đó làm bạn cảm thấy tốt hơn, bạn vẫn vượt xa tôi. :)
couldwasiereisawelba 17/2/2016

2

Lưu macro sau và sử dụng nó cho từng dòng:

qqyy11p/\/\zs1<CR><C-v>10jg<C-a>q

Sự khác biệt chính so với các câu trả lời khác là điều này sử dụng g<C-a>trên một lựa chọn cột làm tăng mỗi dòng với một số khác nhau. Kiểm tra :help v_g_CTRL-Ađể biết thêm thông tin. Tôi cũng đã từng \zschọn vị trí bắt đầu mẫu, sao cho con trỏ dừng ở số sau khi tìm kiếm.

Xin lưu ý rằng bạn cần một phiên bản Vim gần đây để hoạt động.


1
@fruglemonkey cũng đề xuất như vậy . Đây là một tính năng thú vị, mặc dù nó khá gần đây (theo tiêu chuẩn vim), kể từ 7.4.754 chưa được chuyển đến tất cả các bản phát hành.
kba đứng với Monica

Bỏ lỡ nó xin lỗi
Vitor

1
@Vitor Tôi chỉ có gVim 7.4 vì vậy tôi không nghĩ mình có thể làm điều g<C-a>đó @fruglemonkey và bạn đã đề cập, nhưng cảm ơn vì đã phản hồi. Tôi nên lưu ý rằng khi thử macro của bạn - ngay trước khi tôi đến g<C-a>phần, đó không phải là ký tự "1" cuối cùng mà tôi đang tìm cách tăng được tô sáng, mà thay vào đó là ký tự trước "1" đầu tiên "Nhân vật được tô sáng khối. (Ngoài ra, tôi nghĩ rằng nó sẽ có yy11p10jtrong macro, vì tôi đang tìm cách thêm 11 dòng - với tổng số 12.)
Canwasiereisawelba

1
Cảm ơn phản hồi của bạn. Tôi đã cập nhật câu trả lời tương ứng. Quyết định sử dụng \zs, nhưng tôi chỉ có thể thêm vào lsau <CR>.
Vitor

1
Bạn có thể có một số cài đặt trong vimrc của bạn ảnh hưởng đến tìm kiếm biểu thức thông thường. Hãy thử lại bắt đầu Vim với vim -u NONE. Tôi vừa mới làm điều đó và điều này hoạt động hoàn hảo! Trên thực tế, không có cách nào tìm kiếm khớp với 1 đầu tiên vì nó yêu cầu một dấu gạch chéo trước.
Vitor
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.