Có thể giải thích vấn đề
Tôi nghĩ lý do tại sao :g/;/jkhông hoạt động là vì :glệnh hoạt động với thuật toán 2-pass:
- trong lần đầu tiên, nó đánh dấu các dòng chứa mẫu
;
- trong lần chuyển thứ hai, nó hoạt động trên các đường được đánh dấu
Trong lần vượt qua thứ hai, :gnối dòng 1;với dòng 2;vì 1;được đánh dấu trong lần đầu tiên. Tuy nhiên tôi nghi ngờ (không chắc chắn) mà nó không tham gia 1; 2;với 3;vì dòng 2;không tồn tại nữa, nội dung của nó đã được sáp nhập với dòng 1;mà đã được xử lý.
Vì vậy, :gtìm kiếm dòng tiếp theo được đánh dấu trong lần đầu tiên vượt qua ( 3;) và nối nó với dòng sau ( 4;). Sau đó lặp đi lặp lại vấn đề, nó không thể tham gia 3; 4;với 5;vì dòng 4;không tồn tại nữa.
Giải pháp 1 (có vimscript)
Có lẽ bạn có thể gọi một hàm bất cứ khi nào ;tìm thấy một dòng chứa để kiểm tra xem dòng trước đó có chứa dấu chấm phẩy hay không:
function! JoinLines()
if getline(line('.')-1) =~ ';'
.-1join
endif
endfunction
Sau đó sử dụng lệnh toàn cầu sau:
:g/;/call JoinLines()
Hoặc không có chức năng:
:g/;/if getline(line('.')-1) =~ ';' | -j | endif
Giải pháp 2 (không có vimscript)
:g/;/.,/^[^;]*$/-1j
Bất cứ khi nào lệnh toàn cầu :gtìm thấy mẫu, ;nó sẽ thực thi lệnh: .,/^[^;]*$/-1j
Nó có thể được chia nhỏ như thế này:
:g/pattern/a,bj
Ở đâu :
pattern = ;
a = . = number of current line
b = /^[^;]*$/-1 = number of next line without any semicolon minus one
b có thể được chia nhỏ hơn nữa như thế này:
/ = look for the number of the next line matching the following pattern
^ = a beginning of line
[^;] = then any character except a semicolon
* = the last character can be repeated 0 or more times
$ = an end of line
/ = end of pattern
-1 = removes one to the number you just got
jlà dạng viết tắt của lệnh Ex :join, giống như hầu hết các lệnh Ex khác có thể được bắt đầu bằng một phạm vi.
Ở đây, nó đi trước phạm vi: .,/^[^;]*$/-1( a,b)
Một phạm vi theo mẫu a,btrong đó avà bnói chung là 2 số dòng và cho phép bạn hoạt động trên một nhóm các dòng có số nằm giữa avà b, thay vì chỉ một.
Vì vậy, jlệnh kết hợp tất cả các dòng giữa dòng hiện tại ( a) và dòng tiếp theo không chứa bất kỳ dấu chấm phẩy trừ một ( b).
Để biết thêm thông tin, xem:
:help :global
:help :join
:help :range
:g/;/jkhông hoạt động vì nó được thực hiện trong hai lần: đầu tiên bộ đệm được quét, sau đó lệnh được áp dụng cho các dòng khớp.