vim - Làm thế nào để xóa một khối lớn văn bản mà không cần đếm các dòng?


193

Trong vim, tôi thường thấy mình xóa (hoặc sao chép) các khối văn bản lớn. Người ta có thể đếm các dòng văn bản và nói (ví dụ) 50ddđể xóa 50 dòng.

Nhưng làm thế nào người ta có thể xóa khối văn bản lớn này mà không cần phải biết có bao nhiêu dòng để xóa?


1
Nếu cửa sổ đủ lớn, đánh số dòng tương đối hữu ích ở đây. Đặt con trỏ ở trên cùng của cửa sổ, tìm số dòng tương đối của dòng cuối cùng sẽ bị xóa (giả sử, n), thêm một, sau đó nhập số đó, sau đó nhập dd. Ví dụ: nếu n = 50, thì 51dd. Hoặc, sử dụng lệnh chuyển động -50d<down arrow>
BallpointBen

"Tìm số dòng tương đối" - hoặc, sử dụng :set rnuvà Vim sẽ thực hiện việc này ngay lập tức! Dòng bạn đang bật vẫn sẽ được đánh số tuyệt đối, nhưng các dòng trên và dưới con trỏ sẽ được đánh số đối xứng 1, 2, ... (và cập nhật với chuyển động con trỏ, các sự kiện ở cấp độ tệp, v.v.)
John P

Câu trả lời:


287

Tôi không phải là vim guru, nhưng cái tôi sử dụng trong tình huống này là "chế độ trực quan". Trong chế độ lệnh, gõ V(viết hoa). Sau đó di chuyển lên / xuống để tô sáng khối bạn muốn xóa (tất cả các lệnh di chuyển thông thường đều hoạt động). Sau đó loại bỏ nó bằng xhoặc d.


2
Lạ thật. Tôi biết nó hoạt động cho tôi (tm) ở đây trên Linux (vim 7.3.50) và với gVim trên Windows. Và đánh giá bằng các câu trả lời khác, làm việc cho người khác. Có lẽ một số cài đặt trong bạn .vimrcđang làm cho nó hoạt động?
Mat

OK, vì một số lý do tôi đã không nhận ra rằng bạn có thể vào chế độ đường trực quan bằng cách sử dụng Shift- v... Tôi cũng đang cố gắng sử dụng CTRLkhóa. Vì vậy, điều này làm việc và có lẽ là cách thuận tiện nhất.
Justin Ethier

7
Bạn có thể muốn làm rõ rằng có hai chế độ trực quan - Visual Line ( CTRL- v) và Visual Block ( Shift- v).
Justin Ethier

2
Tôi làm điều này rất nhiều. Nhưng tôi luôn coi đó là gian lận và vim kém lý tưởng.
Jim Mitchener

9
Thực tế, có ba chế độ trực quan: Chế độ trực quan (Dựa trên nhân vật {v}), Chế độ dòng trực quan (Dựa trên dòng {Sv}) và Chế độ khối trực quan (Cho phép lựa chọn các khối {Cv})
Tom Regner

293

Đi đến dòng bắt đầu và gõ ma(đánh dấu "a"). Sau đó đi đến dòng cuối cùng và nhập d'a(xóa để đánh dấu "a").

Điều đó sẽ xóa tất cả các dòng từ hiện tại đến đánh dấu (bao gồm). Nó cũng tương thích với, vicũng như vimtrong trường hợp môi trường của bạn không được may mắn sau này.


3
Đá kỳ dị này! Tôi ghét bao lâu tôi chỉ làm một cái gì đó (như đếm dòng) trước khi tôi đi vào một giải pháp tốt hơn. Cảm ơn!
ryanjdillon

1
thực sự tuyệt vời Tôi luôn sử dụng chế độ trực quan để xóa khối nhưng cách này tốt hơn +1
hish

4
Tôi thấy điều này hữu ích hơn chế độ trực quan để xóa 500k + dòng
Michael - Where's Clay Shirky

Câu trả lời thực tế. Tôi sử dụng nó để xóa các thư trong máy chủ của mình khỏi tệp /var/mail/usernamehàng loạt và giữ nguyên các thư cuối cùng. Tôi đánh dấu, sau đó tôi nhập ví dụ 50000tiếp theo ggđể đi đến dòng 50.000, sau đó tôi xóa tất cả các dòng ở giữa. hoạt động như một lá bùa!
otmezger

1
@horta, có lẽ tôi sẽ không sử dụng vimnhư một công cụ để chỉnh sửa các tệp gigabyte - Tôi có xu hướng chọn các công cụ xử lý văn bản như awkvà anh em của nó :-)
paxdiablo

46

Bạn cũng có thể sử dụng chế độ trực quan (một số lệnh cũng có thể sử dụng với tùy chọn xóa) vip vapđể chọn đoạn văn, v2apđể chọn hai đoạn văn cũng daphoạt động d2ap. Bạn có thể xóa trong các khối [ ]nhưda[

Để tham khảo: các loại đối tượng. Từ tài liệu vim: phần 4. http://vimdoc.sourceforge.net/htmldoc/visual.html

4. Operating on the Visual area             *visual-operators*

...    
The objects that can be used are:
aw  a word (with white space)           
iw  inner word                  
aW  a WORD (with white space)           
iW  inner WORD                  
as  a sentence (with white space)           
is  inner sentence                  
ap  a paragraph (with white space)          
ip  inner paragraph                 
ab  a () block (with parenthesis)           
ib  inner () block                  
aB  a {} block (with braces)            
iB  inner {} block                  
a<  a <> block (with <>)                
i<  inner <> block                  
a[  a [] block (with [])                
i[  inner [] block                  

1
da [, da {, da "tất cả đều hữu ích cho các lập trình viên
Rene Wooller

1
cảm ơn! daprất dễ nhớ là "xóa một đoạn"
Tropilio

38

Có nhiều câu trả lời tốt hơn ở đây, nhưng để đầy đủ, tôi sẽ đề cập đến phương pháp tôi đã sử dụng trước khi đọc một số câu trả lời tuyệt vời được đề cập ở trên.

Giả sử bạn muốn xóa từ dòng 24-39. Bạn có thể sử dụng lệnh ex

:24,39d

Bạn cũng có thể kéo các dòng bằng cách sử dụng

:24,39y

Và tìm và thay thế chỉ qua các dòng 24-39 bằng cách sử dụng

:24,39s/find/replace/g

11

Nếu bạn bật số dòng thông qua set numberbạn có thể chỉ cần dNNGxóa dòng NN từ vị trí hiện tại. Vì vậy, bạn có thể điều hướng đến đầu dòng bạn muốn xóa và chỉ cần d50Ggiả sử đó là dòng cuối cùng bạn muốn xóa.


10

Nó phụ thuộc vào khối lớn đó là gì. Có lẽ bạn chỉ muốn xóa một đoạn trong trường hợp a dipsẽ làm.


Cảm ơn vì tiền hỗ trợ. Thật không may, tôi đang làm việc với mã ở đây và thường cần kiểm soát chi tiết hơn thế.
Justin Ethier

1
Tôi cũng đang làm việc với mã và tôi tách các khối logic bằng một dòng trống. Mẹo này chỉ làm cho ngày của tôi. Bây giờ tôi có thể xóa các khối logic lớn bằng ba lần nhấn phím.
tối thiểu

nó hoạt động vì 'd' có nghĩa là xóa, 'p' trong ngữ cảnh này có nghĩa là đoạn văn
user98761

7

Có một số khả năng, những gì tốt nhất phụ thuộc vào văn bản bạn làm việc.

Hai khả năng xuất hiện trong tâm trí:

  • chuyển sang chế độ trực quan ( V,, S-V...), chọn văn bản có chuyển động con trỏ và nhấnd
  • xóa toàn bộ một đoạn với: dap

Bây giờ tôi sử dụng dap rất thường xuyên vì tôi biết về nó và thích tắt và nhúng nó, nhưng, nó luôn xóa một khối và dòng trống đi sau khối, nhưng là một cách để xóa khối và dòng trống đó đến trước nó?
Funkodebat

Ở giữa một văn bản với các đoạn văn không có sự khác biệt cú pháp trong kết quả, phải không? Nếu có tôi đề nghị viết lên những gì bạn muốn, với các ví dụ, trong một câu hỏi mới.
Tom Regner

6

Nếu toàn bộ khối hiển thị trên màn hình, bạn có thể sử dụng cài đặt tương đối. Xem: giúp đỡ tương đối. Có sẵn trong 7.3


Tôi đã không nhận ra cách hữu ích: se rnu là cho đến khi tôi bắt đầu sử dụng nó - tuyệt vời cho biết để 50dd cũng như điều hướng, 50j
rshdev

3

Bạn có thể đặt con trỏ ở đầu hoặc cuối khối và vào chế độ trực quan (shift-v). Sau đó, chỉ cần di chuyển lên hoặc xuống cho đến khi khối mong muốn được tô sáng. Cuối cùng, sao chép văn bản bằng cách nhấn y hoặc cắt văn bản bằng cách nhấn d.


có thể kỳ lạ, nhưng từ đó tôi đã tìm ra cách chọn văn bản từ một số điểm giữa mong muốn trong một dòng và chọn nhiều dòng bên dưới tại cùng một điểm đến cuối mỗi dòng. Chính xác những gì tôi đang tìm kiếm.
nanker

3

Cùng với các chuyển động khác đã được đề cập ở đây, cũng có /{pattern}<CR>chuyển động, vì vậy nếu bạn biết rằng bạn muốn xóa để dòng có chứa foo, bạn có thể làm dV/foo<CR>. Vở đây để buộc chuyển động là khôn ngoan vì theo mặc định /là đặc trưng.


3

Đếm các dòng là quá tẻ nhạt đối với tôi, nhưng đếm 'đoạn văn' không phải là quá tệ. '{' và '}' di chuyển con trỏ đến dòng trống đầu tiên trước và sau con trỏ tương ứng. Các hoạt động di chuyển con trỏ có thể được kết hợp với xóa và một số câu trả lời khác đã sử dụng một cách tiếp cận tương tự (dd cho một dòng, dG cho phần cuối của tài liệu, v.v.)
Ví dụ:

/* Lorem ipsum dolor sit amet, consectetur adipiscing elit. */

Lorem *ipsum(void) {
  return dolor(sit, amet);
}

Nếu con trỏ của bạn bắt đầu phía trên khối nhận xét, 'd}' sẽ xóa khối nhận xét và 'd2}' sẽ xóa cả khối nhận xét và khối mã. Nếu con trỏ của bạn bắt đầu bên dưới khối mã, 'd {' sẽ xóa mã và 'd2 {' sẽ xóa cả hai. Tất nhiên, bạn có thể bỏ qua một khối bằng cách di chuyển con trỏ trước: '{d {' hoặc '} d}'.

Nếu bạn phù hợp với khoảng trắng của bạn hoặc bạn có thể đếm các đoạn trong nháy mắt, điều này sẽ hoạt động. Tệp trợ giúp Vim có nhiều thủ thuật con trỏ hơn nếu bạn quan tâm.


1

Bạn cũng có thể nhập một số rất lớn, sau đó nhấn ddnếu bạn muốn xóa tất cả các dòng bên dưới con trỏ.


Nó có thể thậm chí còn dễ sử dụng hơn dG, nó sẽ xóa đến cuối tài liệu, Gmặc định là đi đến dòng cuối cùng.
andyg0808

1

Xóa một khối văn bản

Giả sử con trỏ của bạn nằm ở đầu khối:

V/^$<CR>d (where <CR> is the enter/return key)

Giải trình

  • Vào chế độ "linewise-visual": V
  • Đánh dấu cho đến dòng trống tiếp theo: /^$<CR>
  • Xóa bỏ: d

Ràng buộc chính

Một giải pháp mạnh mẽ hơn:

:set nowrapscan
:nnoremap D V/^\s*$\\|\%$<CR>d

Giải trình

  • Vô hiệu hóa gói tìm kiếm: :set nowrapscan
  • Ánh xạ lại Dphím (theo các lệnh sau)::nnoremap D
  • Vào chế độ "linewise-visual": V
  • Đánh dấu cho đến dòng trống / khoảng trắng tiếp theo hoặc EOF: /^\s*$\\|\%$<CR>
  • Xóa bỏ: d
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.