Vim: вставка строк построчно


8

Предположим, у меня есть файл, содержащий:

xxx
yyy
zzz

и другой файл:

kkk
qqq
ppp

Я хочу получить:

xxxkkk
yyyqqq
zzzppp

Это возможно в Vim с какой-то командой? (Я пытался использовать VISUAL BLOCK, но безуспешно).

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

Ответы:


12

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

paste -d '\0' file1 file2 > file3

Это именно то, что вы хотите.

Режим Visual Block in vimтакже идеально подходит для этой задачи. Вы уверены, что сделали это правильно? Вам следует

  • Перейти в режим визуального блока
  • Выделите текст и нажмите yдля восстановления
  • Перейдите к другому файлу в верхнем левом углу для вставки данных (последний x) и нажмите p.

Я вставил в Visual Block ... это именно то, что я хотел сделать. Спасибо.
Фабио Ф.

1
По крайней мере, с GNU Coreutils, paste -d '' ...также работает. Интересно, что man-страница coreutils и информационные страницы, по-видимому, не документируют '\ 0', даже если это указано в спецификации Single Unix.
Дероберт

5

Вы можете сделать непосредственно при редактировании file1. Введите :для переключения command modeв vim. Затем введите:

%!paste -d '' - file2

3

Вот способ сделать это в том же файле, используя только Vim.

Это включает в себя некоторое сопоставление клавиш. Однажды я придумал это, когда хотел упорядочить несколько списков в виде таблиц в виде простого текста.

Это полагается на клавишу } (правая фигурная скобка), чтобы пропустить границы абзаца. (Скобки зеркально отражены, кстати: { пропускает к началу файла и } к концу.)

Итак ... предположим, что у вас есть такой файл данных (предполагается, что строки # включены с помощью : set nu ):

+---------------  
| 1 xxx    (cursor on line#1)  
| 2 yyy  
| 3 zzz  
| 4   
| 5 kkk  
| 6 qqq  
| 7 ppp  
+---------------  

Важно, чтобы строка № 4 была пустой строкой (без пробелов), я объясню почему через минуту.

Выполните следующую карту команду:
: карта Q МВТ} jdd'wpkJj

Это связывает клавишу «q» с 12-символьной программой, о которой я подробнее расскажу ниже.

Когда вы нажмете «q», он выполнит эту программу; обратите внимание, что ваш курсор, который начинался со строки № 1, теперь находится на следующей строке и готов снова нажать «q». Вы, возможно, заметили пробел между "xxx kkk"; если вы не хотите этого, посмотрите «А как насчет символа« лишний пробел »?» ниже, ближе к концу.

+---------------
| 1 xxx kkk
| 2 yyy   (cursor on line #2)
| 3 zzz
| 4 
| 5 qqq
| 6 qqq
| ~
+---------------

Вот разбивка отображения:

   :map q mw}jdd'wpkJj
   ^

Двоеточие вводит вас в командный режим, поэтому мы можем выполнить команду «карта».

   :map q mw}jdd'wpkJj
    ^^^^^

Карта q связывает q со следующей последовательностью символов. Обратите внимание, что "q" - это просто моя обычная "map to" key; Вы можете использовать другие ключи. По умолчанию нижний регистр q отображается для начала записи макроса; так как я редко (никогда?) не использую это, я нахожу "q" более полезным для одноразовых служебных макросов. Вы также можете использовать заглавные буквы Q (например, карту Q) или клавишу fnct и т. Д.

Теперь всякий раз, когда вы нажимаете «q» (в режиме навигации), vim будет выполнять эту последовательность нажатий клавиш:

   mw}jdd'wpkJj

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

mw}jdd'wpkJj
^^

В MW Marks поименованный расположение, название здесь «ш». По умолчанию я использую 'w' (я думаю, что это мое 'рабочее место'. Любое именованное местоположение из az будет работать, если вы последовательны.
'W' появится снова через некоторое время, когда мы хочу вернуть курсор на эту строку.

mw}jdd'wpkJj
  ^

Здесь мы имеем правую фигурную }, которая перемещает курсор вниз к границе следующего абзаца; другими словами, это перемещает курсор на следующую пустую строку, которая является строкой # 4 в нашем примере. (Вот почему строка № 4 должна быть пустой строкой; без пробелов, иначе } не будет считать ее границей.)

mw}jdd'wpkJj
   ^

J идет вниз на одну строку; это старая школа vi "hjkl" навигация. Возможно, вы могли бы использовать здесь и стрелку вниз, я считаю, что букву «j» несколько легче читать и легче использовать (потому что клавиши со стрелками не всегда находятся в одном и том же месте между различными марками клавиатур для ноутбуков и настольных ПК, но «hjkl» msgstr "Гарантировано, что он всегда находится справа от домашней строки любой клавиатуры QWERTY (что помогает моей скорости набора текста)).
В любом случае, в этот момент курсор находится на строке № 5.

+---------------  
| 1 xxx
| 2 yyy  
| 3 zzz  
| 4   
| 5 kkk   (cursor on line#5)
| 6 qqq  
| 7 ppp  
+---------------  

mw}jdd'wpkJj
    ^^

Дд является команда редактирования «Удалить строку», поэтому он удаляет текущую строку, которая является строка # 5 с «ККК» на нем. Удаление строки также помещает ее в буфер вставки по умолчанию, который мы будем использовать эксплойтом, чтобы вернуть «kkk» туда, где мы хотим, в строке # 1, рядом с «xxx».

mw}jdd'wpkJj
      ^^

Последовательность 'w (одинарная кавычка w) возвращает курсор к нашей закладке для "w", которая помещает курсор в строку # 1.

mw}jdd'wpkJj
        ^

Строчная буква «p» ставит текущий буфер по умолчанию (с «kkk», как вы помните) после курсора. Так как буфер содержит то, что раньше было строкой № 5, наш файл теперь кратко выглядит так:

+---------------
| 1 xxx
| 2 kkk    (cursor on line#2, after the freshly restored "kkk")
| 3 yyy
| 4 zzz
| 5 
| 6 qqq
| 7 ppp
+---------------

Обратите внимание, как "kkk" стал строкой № 2. (Я не могу легко проиллюстрировать, где находится курсор ... он должен быть в начале строки № 2).
Мы близко, но еще не совсем там ...

mw}jdd'wpkJj
         ^^

Строчные к хмель курсора к линии № 1 ( «hjkl» навигация снова), и верхний регистр J присоединяется к следующей строке на текущую строку, что делает наш файл выглядеть следующим образом (курсор находится все еще на линии # 1, между х и к):

+---------------
| 1 xxx kkk    (cursor on line #1, between 'xxx' and 'kkk')
| 2 yyy
| 3 zzz
| 4 
| 5 qqq
| 6 ppp
+---------------


mw}jdd'wpkJj
           ^

Последняя j - это навигация "hjkl" еще раз, которая перемещает курсор вниз на строку # 2, что удобно, потому что это следующая строка, к которой мы хотим применить q .
В любом случае, это будет выглядеть так:

+---------------
| 1 xxx kkk
| 2 yyy       (cursor on #2)
| 3 zzz
| 4 
| 5 qqq
| 6 ppp
+---------------

Если вы нажмете «q» еще раз, и это будет выглядеть так (обратите внимание, курсор находится на строке № 3).

+---------------
| 1 xxx kkk
| 2 yyy qqq
| 3 zzz        (cursor on #3)
| 4 
| 5 ppp
+---------------

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

Вот более длинный пример. Добавление пустой строки в строке № 7 приводит к тому, что «ggg» будет помещаться первым в следующем столбце. После перехода к «lll», переместите курсор обратно к строке # 1 (левый вьющийся, {, для этого хорошо работает) и продолжайте нажимать «mmm». Если вы решили, что вам не совсем нравится то, как оно устроено, удерживайте u (отменить) немного и настройте, где находится ваша «граница», затем начните сначала.

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

+----------:---------------------------
|   before : after
+----------:---------------------------
|  1 aaa   :  1 aaa ggg mmm sss yyy
|  2 bbb   :  2 bbb hhh nnn ttt zzz
|  3 ccc   :  3 ccc iii ooo uuu
|  4 ddd   :  4 ddd jjj ppp vvv
|  5 eee   :  5 eee kkk qqq www
|  6 fff   :  6 fff lll rrr xxx
|  7       :-------------------------
|  8 ggg 
|  9 hhh 
| 10 iii 
| 11 jjj 
| 12 kkk 
| 13 lll 
| 14 mmm 
| 15 nnn 
| 16 ooo 
| 17 ppp 
| 18 qqq 
| 19 rrr 
| 20 sss 
| 21 ttt 
| 22 uuu 
| 23 vvv 
| 24 www 
| 25 xxx 
| 26 yyy 
| 27 zzz
+----------

А как насчет персонажа Extra Space?
Часть поведения команды Join заключается в том, что она помещает пробел между строками, к которым она присоединяется.
Если вам не нужен пробел между «xxx kkk», вы можете
добавить команду delete (x) в строку:

simple join (space char):  :map q mw}jdd'wpkJj
join + x (kills space):    :map q mw}jdd'wpkJxj
join w/comma:              :map q mw}jdd'wpkJR,^[j

«Объединить + х» убивает пространство, используя х сразу после того, как мы соединяем две строки вместе. x в режиме навигации удаляет любой символ, на котором находится курсор, который в данном случае был символом пробела.

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

:map q mw}jdd'wpkJR,^[j
                  ^

R ставит нас в режим редактирования ( в частности , режим Замены, который будет перезаписывать любые символы , с тем, что мы типа).

 :map q mw}jdd'wpkJR,^[j
                    ^

, Буквально типы запятой, которое перезаписывает обижая пространство в этой точке.

 :map q mw}jdd'wpkJR,^[j
                     ^^

И затем ^ [ сигнализирует о побеге, который покидает режим редактирования и возвращает нас в режим навигации.
Теперь мы готовы к заключительному J , чтобы взять нас вниз к следующей строке.

Чтобы отобразить escape-символ, вам нужно нажать ^ Q (windows) или ^ V (linux & unix), а затем нажать клавишу Esc (если вы этого не сделаете, символ Esc прервет команду, а слева вас интересует, почему ваша возможно сложная карта определение просто пропало). Вот последовательность, которую вам нужно будет ввести, чтобы получить ее в Vim на Windows:

:map q mw}jdd'wpkJR,<Ctr-Q><Esc>j

Так. Есть, вероятно, десятки способов сделать такое, Vim.
Когда имеют значение «полевые» разделители, я обычно помещаю простую уникальную последовательность в конец каждой строки с глобальным поиском и заменой, продолжаю и объединяю столбцы так, как я хочу, а затем заменяю все, чтобы получить конкретный разделитель, который я хочу ,

Во всяком случае, это только один пример. Надеюсь, вам было интересно.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.