Я думаю, що наступна команда повинна працювати:
:%s/^\(.*\)\(\n\1\)\+$/\1/
Пояснення:
Ми використовуємо команду підстановки для всього файлу, щоб перейти pattern
на string
:
:%s/pattern/string/
Ось pattern
це ^\(.*\)\(\n\1\)\+$
і string
є \1
.
pattern
може бути розбита так:
^\(subpattern1\)\(subpattern2\)\+$
^
і $
збігаються відповідно початок рядка і кінець рядка.
\(
і \)
використовуються для додавання, subpattern1
щоб ми могли посилатися на це пізніше за спеціальним номером \1
.
Вони також використовуються для укладання, subpattern2
щоб ми могли повторити це 1 або більше разів із кількісним показником \+
.
subpattern1
є .*
.
метахарактором, що відповідає будь-якому символу, крім нового рядка, і *
є кількісним показником, що відповідає останньому символу 0, 1 або більше разів.
Так .*
відповідає будь-якому тексту, що не містить нового рядка.
subpattern2
є збігом \n\1
\n
нового рядка та \1
збігається з тим самим текстом, який був узгоджений усередині першого \(
, \)
що тут subpattern1
.
Тож pattern
можна прочитати так:
початок рядка ( ^
), за яким слід будь-який текст, що не містить нового рядка ( .*
), а потім новий рядок ( \n
), потім той самий текст ( \1
), останні два повторюються один або кілька разів ( \+
), і нарешті кінець рядка ( $
) .
Де б pattern
не було зібрано (блок однакових рядків), команда supstitution замінює його, string
яким є тут \1
(перший рядок блоку).
Якщо ви хочете побачити, на які блоки рядків буде впливати, не змінюючи нічого у вашому файлі, ви можете увімкнути цю hlsearch
опцію та додати n
прапор заміни в кінці команди:
:%s/^\(.*\)\(\n\1\)\+$/\1/n
Для більш детального контролю ви також можете попросити підтвердження перед зміною кожного блоку рядків, додавши c
натомість прапор заміни:
:%s/^\(.*\)\(\n\1\)\+$/\1/c
Для отримання додаткової інформації про команду читанні підстановки :help :s
,
для заміщення прапорів :help s_flags
,
для різних метасимволов і квантори читання :help pattern-atoms
, так
і для регулярних вирази в Vim прочитати це .
Редагувати: Wildcard вирішив проблему в команді, додавши в $
кінці pattern
.
Також BloodGain має більш коротку та читану версію тієї ж команди.
$
в цьому, хоча. В іншому випадку він буде робити несподівані речі з рядком, який починається з ідентичного тексту з попереднім рядком, але має деякі інші символи. Також зауважте, що основна команда, яку ви дали, є функціонально еквівалентною моїй відповіді:%!uniq
, але прапорці підсвітки та підтвердження приємні.