Як це зробити у Vim:
ПЕРЕД:
aaa
bbb
ccc
ddd
eee
fff
ПІСЛЯ:
aaa
ccc
eee
Як це зробити у Vim:
ПЕРЕД:
aaa
bbb
ccc
ddd
eee
fff
ПІСЛЯ:
aaa
ccc
eee
Відповіді:
Для цього можна використовувати макрос. Виконайте наступне.
gg
.qq
.dd
після.q
.10000@q
PS: Щоб перейти в командний режим, просто натисніть клавішу Escape кілька разів.
:g/^/+d
від користувача stackoverflow.com/users/254635/ib (нижче) - це більш елегантний спосіб вирішити цю проблему.
Елегантний (та ефективний) спосіб виконати завдання - викликати :+delete
команду, видаляючи рядок, що стоїть за поточним, на кожному рядку за допомогою :global
команди:
:g/^/+d
:1d|g/^/+d
видаляє непарні рядки.
Ми можемо використовувати :normal
або :norm
для виконання заданих команд у звичайному режимі. Джерело
:%norm jdd
%norm ddj
не працює, якщо ви хочете видалити непарні рядки.
:map ^o ddj^o
^o
Тут ^ означає CTRL. Рекурсивний макрос для видалення рядка кожні два рядки. Добре виберіть свій перший рядок, і все готово.
з архіву пошти vim :
:let i=1 | while i <= line('$') | if (i % 2) | exe i . "delete" | endif | let i += 1 | endwhile
(Якщо набрати один рядок у командному рядку vim, буде видалено рядок 1,3,5,7, ...)
!perl -ne 'print unless $. % 2'
:-)
if (expression)
яка також працює для кожного третього рядка і т. Д.
Ви завжди можете скопіювати команду оболонки, що означає, що ви можете використовувати будь-яку мову сценаріїв, яка вам подобається:
:%!perl -nle 'print if $. % 2'
(або використовуйте "якщо" замість "якщо", залежно від того, які рядки ви хочете)
-l
перехід на Perl ... також, я б сказав, що awk
це трохи ширше, ніж Perl, хоча насправді це не так вже й багато в наші дні, і це можна зробити коротше:, :%!awk NR\%2
або :%!awk 1-NR\%2
для інших рядків.
:%!awk -- '++c\%2'
альтернативно
:%!awk -- 'c++\%2'
залежно від того, яку половину ви хочете відсіяти.
NR
змінну?
:%!awk NR\%2
або :%!awk 1-NR\%2
, як я писав в іншому коментарі. Це навряд чи довше.
1-NR
довше ніж c++
. Так, я знаю, що це один персонаж. Як я вже сказав - справжня причина в тому, що я про це забув. У будь-якому випадку, схоже, люди тут не цінують красу awk.
NR
коротший ніж ++c
:)
Ви можете використовувати власні можливості пошуку та заміни Vim так: Помістіть курсор у перший рядок і введіть у звичайному режимі:
:.,/fff/s/\n.*\(\n.*\)/\1/g
.,/fff/
Є діапазон для заміщення. Це означає "від цього рядка до рядка, що відповідає регулярному виразуfff
(в даному випадку останньому рядку).s///
є заміною команди. Він шукає регулярний вираз і замінює кожне його появу рядком. Theg
На кінцях засобів повторити заміну тих пір , поки регулярний вираз продовжує бути знайдено.\n.*\(\n.*\)
відповідає .*
новому рядку , потім цілому рядку ( відповідає довільній кількості символів, крім нового рядка), потім іншому новому рядку та іншому рядку. Дужки \(
і \)
спричиняють запис виразу всередині них, тому ми можемо використовувати його пізніше, використовуючи\1
.\1
вставляє згрупований новий рядок і рядок після нього назад, тому що ми не хочемо, щоб пройшов і наступний рядок - ми просто хочемо, щоб механізм заміщення пройшов повз нього, щоб ми не видаляли його під час наступної заміни.Таким чином ви можете контролювати діапазон, в якому ви хочете, щоб відбулося видалення, і вам не потрібно використовувати будь-який зовнішній інструмент.
$
замість /fff/
, для кінця файлу, незалежно від його вмісту.
В якості іншого підходу ви також можете використовувати python, якщо ваш vim має для цього підтримку.
:py import vim; cb = vim.current.buffer; b = cb[:]; cb[:] = b[::2]
b = cb[:]
тимчасово копіює всі рядки поточного буфера в b
. b[::2]
отримує кожен другий рядок з буфера і призначає його всьому поточному буферу cb[:]
. Копія в b
необхідна, оскільки буферні об'єкти, схоже, не підтримують синтаксис розширеного фрагмента.
Це, мабуть, не "vim шлях", але простіше запам'ятати, якщо ви знаєте python.
Видалити непарні рядки (1,3,5, ..) -> :%s/\(.*\)\n\(.*\)\n/\2\r/g
Видалити парні рядки (2,4,6, ..) -> :%s/\(.*\)\n.*\n/\1\r/g
Шукайте текст (формує перший рядок), а потім новий символ рядка та ще деякий текст (формує другий рядок), а потім інший новий символ рядка, і замінюйте вищезазначене або першим збігом (непарний рядок), або другим збігом (парним рядком) з наступним поверненням карети.
ви можете спробувати це у vim
:1,$-1g/^/+1d
Я постараюся бути більш чітким (дві частини)
перша частина діапазон виділення ( :from,to
)
друга частина дія ( d
видалити)
:1,$-1
)g
) delete ( +1d
) наступний рядокВи можете спробувати перейти до першого рядка вашого файлу та виконати :+1d
, і наступний рядок зникне
Я знаю, що це брудно, але це vim, і це працює