vim - Як видалити великий блок тексту, не рахуючи рядки?


193

У vim, мені часто здається, що я видаляю (або копіюю) великі блоки тексту. Можна порахувати рядки тексту і сказати (наприклад), 50ddщоб видалити 50 рядків.

Але як би видалити цей великий блок тексту, не знаючи, скільки рядків видалити?


1
Якщо вікно досить велике, тут корисна відносна нумерація рядків. Помістіть курсор у верхній частині вікна, знайдіть відносний номер останнього рядка, який потрібно видалити (скажімо, n), додайте його, потім введіть це число, а потім введіть dd. Наприклад , якщо N = 50, то 51dd. Як варіант, скористайтеся командою руху -50d<down arrow>
BallpointBen

"Знайдіть відносний номер рядка" - або, використовуйте, :set rnuі Vim зробить це миттєво! Рядок, на якому ви перебуваєте, все одно буде пронумерований абсолютно, але рядки над і під курсором будуть симетрично пронумеровані 1, 2, ... (та оновлення з переміщенням курсора, подіями на рівні файлів тощо)
Джон П

Відповіді:


287

Я не гум вим, але те, що я використовую в цій обставині, - це "візуальний режим". У командному режимі введіть V(заголовок). Потім перемістіться вгору / вниз, щоб виділити блок, який потрібно видалити (працюють всі звичайні команди руху). Потім видаліть його за допомогою xабо d.


2
Дивно. Я знаю, що це працює для мене (tm) тут на Linux (vim 7.3.50) та з gVim у Windows. І судячи з інших відповідей, працює для інших людей. Можливо, деякі налаштування у вашому .vimrcпроцесі змушують його діяти?
Мат

Гаразд, я чомусь не зрозумів, що ви можете входити в режим візуального рядка, використовуючи Shift- v... я також намагався використовувати CTRLключ. Тож це працює і, мабуть, найзручніший спосіб.
Джастін Етьє

7
Ви можете уточнити, що існують два візуальні режими - Visual Line ( CTRL- v) та Visual Block ( Shift- v).
Джастін Етьє

2
Я цим багато займаюся. Але я завжди вважаю це обманом і менш ідеальним vim.
Джим Мітченер

9
Насправді є три візуальні режими: Візуальний режим (на основі символів {v}), режим режиму візуальних ліній (на основі рядків {Sv}) та режим візуального блоку (дозволяє
виділити

293

Перейдіть до початкового рядка та введіть ma(позначте «а»). Потім перейдіть до останнього рядка та введіть d'a(видаліть, щоб позначити "а").

Це видалить усі рядки з поточного до позначеного (включно). Це також сумісне з vi, а також vim, за винятком випадків, що ваше оточення не буде благословлено останніми.


3
Це вигадливі скелі! Я ненавиджу, як довго я щось роблю (наприклад, підрахунок рядків), перш ніж перейти до кращого рішення. Дякую!
ryanjdillon

1
дійсно приголомшливо, я завжди використовую візуальний режим для видалення блоку, але цей спосіб краще +1
hish

4
Я вважаю це кориснішим за візуальний режим для видалення 500k + рядків
Michael - Де Clay Shirky

Дійсно практична відповідь. Я використовую його для видалення листів на своєму сервері з файлу /var/mail/usernameмасово, а останню пошту залишаю недоторканою. Я роблю позначку, потім вводжу, наприклад, 50000після чого ggпереходжу до рядка 50.000, потім видаляю всі рядки між ними. працює як шарм!
otmezger

1
@horta, я, мабуть, не використовував vimби інструмент для редагування гігабайтних файлів - я схильний вибирати такі інструменти для обробки тексту, як awkі його брати :-)
paxdiablo

46

Ви можете використовувати візуальний режим також (деякі команди можуть використовуватися з опцією видалення також) , vip vapщоб вибрати пункт, v2apщоб вибрати один з двох параграфів dapроботи, d2apтакож. Ви можете видалити в межах [ ]подібних блоківda[

Для довідки: типи об’єктів. З документації VIM: розділ 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 "все корисне для програмістів
Рене Вуллер

1
Дякую! dapдуже легко запам'ятовується як "видалити абзац"
Тропіліо

38

Тут є багато кращих відповідей, але для повноти я згадаю метод, який я використовував, перш ніж читати деякі великі відповіді, згадані вище.

Припустимо, ви хочете видалити з рядків 24-39. Ви можете використовувати команду ex

:24,39d

Ви також можете підтягувати лінії за допомогою

:24,39y

І знайдіть і замініть трохи більше рядків 24-39, використовуючи

:24,39s/find/replace/g

11

Якщо ви ввімкнете номери ліній через set numberвас, ви можете просто dNNGвидалити рядок NN з поточного положення. Таким чином, ви можете перейти до початку рядка, який ви хочете видалити, і просто d50Gприпустивши, що це останній рядок, який ви хочете видалити.


10

Це свого роду залежить від того, що це великий блок . Можливо, ви просто маєте на увазі видалити абзац, у такому випадку а dip.


Дякую за пораду. На жаль, я працюю з кодом тут, і зазвичай мені потрібен більш тонкий контроль, ніж цей.
Джастін Етьє

1
Я теж працюю з кодом, і розділяю логічні блоки порожнім рядком. Ця порада просто зробила мені день. Тепер я можу видалити великі блоки логіки за допомогою трьох натискань клавіш.
мінімум

працює, тому що "d" означає видалити, "p" у цьому контексті означає абзац
user98761

7

Є кілька можливостей, що найкраще залежить від тексту, над яким ви працюєте.

Приходять до уваги дві можливості:

  • перейти у візуальний режим ( V,S-V , ...), виділіть текст з рухом курсору і натиснітьd
  • видаліть цілий абзац за допомогою: dap

Я дуже часто використовую Дап зараз, коли я знаю про це, і віддаю перевагу його відключенню та зануренню, але він завжди видаляє блок і порожню лінію, що надходить після блоку, але це був спосіб видалити блок та порожній рядок, який приходить до цього?
Funkodebat

У середині тексту з абзацами немає синтаксичної різниці в результаті, чи є? Якщо є, я пропоную написати нове запитання, на прикладі якого ви хочете.
Том Регнер

6

Якщо весь блок видно на екрані, ви можете використовувати відносну кількість параметрів. Див.: Допомога відноснокілька. Доступно в 7.3


Я не усвідомлював, наскільки корисний: se rnu, поки я не почав його використовувати - чудово, що знаю 50dd, а також навігацію, 50j
rshdev

3

Ви можете розмістити курсор на початку чи в кінці блоку та увійти у візуальний режим (shift-v). Потім просто рухайтеся вгору або вниз, поки не виділиться потрібний блок. Нарешті, скопіюйте текст, натиснувши y, або виріжте текст, натиснувши d.


може бути дивним, але з цього я зрозумів, як вибрати текст з якоїсь потрібної середини в рядку і вибрати кілька рядків нижче в тій же точці до кінця кожного рядка. Саме те, що я шукав.
nanker

3

Поряд з іншими пропозиціями, які вже згадуються тут, є і /{pattern}<CR>рух, тому якщо ви знаєте, що ви хочете видалити рядок, що містить foo, ви могли б зробити dV/foo<CR>. Vтут, щоб примусити рух бути лінійним, тому що за замовчуванням /є символом.


3

Підрахунок рядків для мене занадто виснажливий, але підрахунок «абзаців» не так вже й поганий. '{' і '}' переміщують курсор до першого порожнього рядка перед курсором і після нього відповідно. Операції з переміщення курсору можуть поєднуватися зі видаленням, і в декількох інших відповідях використовується аналогічний підхід (dd для рядка, dG для кінця документа тощо).
Наприклад:

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

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

Якщо ваш курсор починається над блоком коментарів, 'd}' видаляє блок коментарів, а 'd2}' видаляє і блок коментарів, і блок коду. Якщо ваш курсор починається нижче блоку коду, 'd {' видаляє код, а 'd2 {' видаляє обидва. Звичайно, ви можете пропустити один блок, перемістивши курсор спочатку: '{d {' або '} d}'.

Якщо ви узгоджуєтесь зі своїм пробілом або ви можете порахувати абзаци з першого погляду, це має спрацювати. У файлі довідки Vim, якщо ви зацікавлені, є більше курсових рекомендацій.


1

Ви також можете ввести дуже велику кількість, а потім натисніть, ddякщо хочете видалити всі рядки під курсором.


Це може бути ще простішим у використанні dG, яке видаляється до кінця документа, як Gза замовчуванням для переходу до останнього рядка.
andyg0808

1

Видалення тексту тексту

Припустимо, що ваш курсор сидить на початку блоку:

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

Пояснення

  • Введіть режим "лінійно-візуальний": V
  • Виділіть до наступного порожнього рядка: /^$<CR>
  • Видалити: d

Ключова прив'язка

Більш надійне рішення:

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

Пояснення

  • Вимкнути обгортку пошуку: :set nowrapscan
  • Перейдіть Dклавішу (до наступних команд)::nnoremap D
  • Введіть режим "лінійно-візуальний": V
  • Виділіть до наступної порожньої / пробільної лінії або EOF: /^\s*$\\|\%$<CR>
  • Видалити: d
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.