vim - как выделить несколько строк? - PullRequest
0 голосов
/ 15 апреля 2019

Скажите, у меня есть этот текст:

#!/bin/bash
# Get host
db_host=$(echo "dbhost") 
# Get DB name
db_name=$(echo "dbname")
# Get user
db_user=$(echo "dbuser")
# Get password
db_pass=$(echo "dbpass")

и я хочу выбрать каждое имя переменной и произвести вывод ниже текста:

echo "db_host: $db_host"
echo "db_name: $db_name"
echo "db_user: $db_user"
echo "db_pass: $db_pass"

В возвышенном , например, я выделю =$( и нажму + d несколько раз, вернусь к началу строки, скопируйте с помощью SHIFT + , перейдите к последней строке и создайте новую, вставьте, выделите все новые строки, нажмите + SHIFT + l и затем добавьте все, что я хочу.

Я использую vim multiple cursors, но я не уверен, что это путь. Есть направления?

Ответы [ 4 ]

3 голосов
/ 15 апреля 2019

Есть много способов сделать это. Вот один из них: Начиная с курсора в начале первого db_host:

yGGp              Yank everything, paste at the bottom
:.,$g/^#/d<CR>    In the pasted part, remove all comment lines
<C-O>             Back to start of the pasted part
<C-V>GI           Select the first column, prepend
echo "<Esc>
f=<C-V>           Then select the block from equals to quote, change
f"Gc
: $<Esc>
f)<C-V>           Then select the block at the closing brace, change
G$c
;<Esc>

Другой подход, использующий макросы и регистры, начиная с той же позиции:

qqq               Clear register q
qwq               Clear register w
qq                Start recording macro in q
yaw               yank a word (db_name) to default register
o                 open a new line below, and start insert
echo "
<C-R>"            insert the content of the default register (db_name)
: $
<C-R>"            insert the content of the default register (db_name) again
"<Esc>
"Wdd              the line is done; yank-append to register w
j0                skip the comment line, position at the start of the next variable
@q                execute the q macro (which is currently empty, but not for long)
q                 save the q macro
@q                execute the q macro (which will recurse, and slurp up all lines)
"wp               paste all the accumulated lines at the bottom

Третий, используя регулярное выражение:

:.,$v/^#/t$<CR>   copy all non-comment lines to the end
:-3,.s/\(\w\+\).*/echo "\1: $\1"/<CR>
                  I didn't set a mark so manual range from 3 lines above:
                  capture the first word, discard everything else,
                  replace with what we want (obviously, could have done
                  visual selection instead of manually setting range)
0 голосов
/ 15 апреля 2019

Может быть, я пропустил то, что вы пытаетесь сделать, но если я правильно понял, вы просто хотите обновить формат вывода.

Попробуйте это:

:g/[(]echo "/s/echo "\([^"]*\)"\(.*\)$/echo "\1"\2^Mecho "\1: $\1"/

ПРИМЕЧАНИЕ: ^ M - это один управляющий символ, НЕ КАРАТ, а затем M.
См. Ниже.

До -

#!/bin/bash
# Get host
db_host=$(echo "dbhost")
# Get DB name
db_name=$(echo "dbname")
# Get user
db_user=$(echo "dbuser")
# Get password
db_pass=$(echo "dbpass")

После -

#!/bin/bash
# Get host
db_host=$(echo "dbhost")
echo "dbhost: $dbhost"
# Get DB name
db_name=$(echo "dbname")
echo "dbname: $dbname"
# Get user
db_user=$(echo "dbuser")
echo "dbuser: $dbuser"
# Get password
db_pass=$(echo "dbpass")
echo "dbpass: $dbpass"

Объяснение

:g/[(]echo "/s/echo "\([^"]*\)"\(.*\)$/echo "\1"\2^Mecho "\1: $\1"/

в штуках -

:g/pat/cmd

Это говорит "глобально" в каждой строке, соответствующей "pat" do "cmd". Мой "кусочек" был вашим (echo ", а мой "cmd" - замена.

s/echo "\([^"]*\)"\(.*\)$/echo "\1"\2^Mecho "\1: $\1"/

Я сказал заменить echo "..."... и запомнить, что было между кавычками как 1, и что-нибудь после как 2.

В заменяемой части написано, что нужно вернуть все, что там было (echo "\1"\2), а затем немного махинаций.

Нажав CTRL-V Я вошел в режим цитаты, который позволил мне нажать CTRL-M , чтобы вставить возврат каретки , который vim преобразуется при выполнении в новую строку, по крайней мере, в версии, которые я использовал.

Это трюк. Это может быть удобно знать и использовать, но всегда имейте в виду, что такие вещи в основном являются хакерскими. Caveat Scriptor.

Я добавил это в отформатированном echo "\1: $\1", чтобы добавить нужные строки.

0 голосов
/ 15 апреля 2019

Немного другое решение:

:g/echo/t$
:-3,.normal! ywccecho "<Ctrl-v><Ctrl-r>0: $<Ctrl-v><Ctrl-r0"

Пояснение

:g ................... global command
/echo/ ............... applied on each line that has "echo"
t$ ................... copy to the end

Курсор переместится в конец, поэтому мы устанавливаем интервал в минус три строки до текущей строки -3,.

yw ................... copy the first word
cc ................... start chnanging the whole line
echo " ............... inserts a literal `echo "`
Ctrl-v Ctrl-r 0 ...... inserts the word we copied

Примечание. Чтобы вставить регистр ноль 0, необходимо набрать Ctrl-v Ctrl-r 0

Использование команды замены вместо обычной

Вторая команда может быть заменой

:-3,.s/\v(^\w+).*/echo "\1: $\1"

Как решение vim может быть более разумным решением?

Если вам нужно изменить сотни или тысячи строк, я думаю, что несколько курсоров не сильно помогут, особенно если шаблон чередуется по нескольким строкам.

0 голосов
/ 15 апреля 2019

Вот как я бы это сделал:

Сначала создайте эхо-строки с подстановкой:

:%s/\(db_\w\+\)=\$(echo "\w\+")/&\recho "\1: $\1"

Обратите внимание на & в замене, которая соответствует целомулиния.Затем следует \r для новой строки.

Затем очистите регистр, который вы будете использовать для него (a в моем случае):

qaq

Затем отрежьте все линии эхав указанном регистре:

:g/^echo /d A

Наконец, перейдите туда, где вы хотите, чтобы они были, и вставьте содержимое регистра:

"ap
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...