Понимание различий между ссылками на строки через: г / ^ / норма и через:% норма

8

Допустим, у меня есть следующий очень простой файл

a
b
c
d
e

и я решил, что я хочу добавить пустые строки после каждой строки. Несколько разных методов сразу приходят мне на ум. Мы могли бы просто сделать это (и таким образом принять неудачу). Мы могли бы записать макрос qqo<ESC>jqи повторить его несколько раз.

Два других метода казались мне более очевидными в то время.

Во-первых, я думал, что буду вводить :normкоманду oв каждой строке. Итак, я бегу :%norm o. Но в действительности мы получаем 5 пустых строк, за которыми следуют неразделенные строки, как указано выше. Я понимаю, что это означает, что %normvim на самом деле принимает сообщение о выдаче следующей обычной команды в первых пяти строках этого файла из пяти строк . Команда oсоздает новую строку, а vim «тупой» в том смысле, что она ссылается по номеру строки, а не по какому-то другому идентификатору.

Ну, я был смущен. Конечно. Я попробовал несколько других вещей, чтобы увидеть, смогу ли я заставить вышеуказанный метод работать, но, увы, я не смог. Из любопытства я попробовал другой мой любимый метод массового применения. Это заставило меня попробовать :g/^/norm o. К моему удивлению, это работает просто отлично! Так что, на мой взгляд, vim здесь не "тупой" так же, как выше, и ссылается на строки не просто на номер строки.

Что именно происходит?

davidlowryduda
источник
2
На стороне записки вы также можете сделать это следующим образом : :%s/$/\r/или так: :%s/\n/\r\r/. Вывод заключается в том, что с символами новой строки можно сопоставить \n, но они должны быть записаны как \rзначения замены
lcd047

Ответы:

9

Ну, %это сокращение от 1,$(диапазон от первой строки до последней). От :he :%:

Line numbers may be specified with:             :range E14 {address}
        {number}        an absolute line number
        .               the current line                          :.
        $               the last line in the file                 :$
        %               equal to 1,$ (the entire file)            :%

И для :global:

The global commands work by first scanning through the [range] lines and
marking each line where a match occurs (for a multi-line pattern, only the
start of the match matters).
In a second scan the [cmd] is executed for each marked line with its line
number prepended.  For ":v" and ":g!" the command is executed for each not
marked line.  If a line is deleted its mark disappears.

Итак, первый случай подобен обходу списка при его изменении, поэтому счетчик элементов списка становится недействительным. Во втором случае мы помечаем элементы, на которые хотим нацелиться, за один проход, так что даже если список изменяется на втором проходе, мы все равно знаем, над какими элементами мы хотим работать.

Мур
источник
Ах, это даже в файле справки для глобальных. Как глупо я. Спасибо
давидловрыдуда
Человек - g это безумно полезно я должен потратить больше времени, чтобы перейти от среднего пользователя vi к
опытному