Vim: вставка строк линию за линией

Я сделал маленький сравнительный тест. Это только тестирует записи все же.

Данные тестирования являются исходным деревом ядра Linux (linux-3.8), уже распакованный в память (/dev/shm/tmpfs), таким образом, должно быть как можно меньше влияния от источника данных. Я использовал сжимаемые данные для этого теста, так как сжатие с несжимаемыми файлами не имеет смысла независимо от шифрования.

Используя btrfs файловую систему на объеме LVM на 4 ГиБ, на LUKS [AES, xts-плоскость, sha256], на RAID-5 более чем 3 диска с 64 КБ chunksize. ЦП является Intel E8400 2x3Ghz без AES-NI. Ядро является 3.8.2 x86_64.

Сценарий:

#!/bin/bash

PARTITION="/dev/lvm/btrfs"
MOUNTPOINT="/mnt/btrfs"

umount "$MOUNTPOINT" >& /dev/null

for method in no lzo zlib
do
    for iter in {1..3}
    do
        echo Prepare compress="$method", iter "$iter"
        mkfs.btrfs "$PARTITION" >& /dev/null
        mount -o compress="$method",compress-force="$method" "$PARTITION" "$MOUNTPOINT"
        sync
        time (cp -a /dev/shm/linux-3.8 "$MOUNTPOINT"/linux-3.8 ; umount "$MOUNTPOINT")
        echo Done compress="$method", iter "$iter"
    done
done

Таким образом в каждом повторении, это делает новую файловую систему и измеряет время, которое требуется для копирования источника ядра Linux из памяти и umount. Таким образом, это - чистый тест записи, нулевые чтения.

Результаты:

Prepare compress=no, iter 1

real 0m12.790s
user 0m0.127s
sys 0m2.033s
Done compress=no, iter 1
Prepare compress=no, iter 2

real 0m15.314s
user 0m0.132s
sys 0m2.027s
Done compress=no, iter 2
Prepare compress=no, iter 3

real 0m14.764s
user 0m0.130s
sys 0m2.039s
Done compress=no, iter 3
Prepare compress=lzo, iter 1

real 0m11.611s
user 0m0.146s
sys 0m1.890s
Done compress=lzo, iter 1
Prepare compress=lzo, iter 2

real 0m11.764s
user 0m0.127s
sys 0m1.928s
Done compress=lzo, iter 2
Prepare compress=lzo, iter 3

real 0m12.065s
user 0m0.132s
sys 0m1.897s
Done compress=lzo, iter 3
Prepare compress=zlib, iter 1

real 0m16.492s
user 0m0.116s
sys 0m1.886s
Done compress=zlib, iter 1
Prepare compress=zlib, iter 2

real 0m16.937s
user 0m0.144s
sys 0m1.871s
Done compress=zlib, iter 2
Prepare compress=zlib, iter 3

real 0m15.954s
user 0m0.124s
sys 0m1.889s
Done compress=zlib, iter 3

С zlib это намного медленнее, с lzo немного быстрее, и в целом, не стоящий беспокойства (разница является слишком небольшой для моего вкуса, полагая, что я использовал легкие к сжатию данные для этого теста).

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

8
05.06.2014, 16:59
3 ответа

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

paste -d '\0' file1 file2 > file3

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

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

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

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

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

Для пропуска границ абзаца используется клавиша } (правая фигурная скобка). (Фигурные скобки являются зеркальными, кстати: { переходит к началу файла, а } к концу.)

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

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

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

Выполните следующую команду map :
: map q mw} jdd'wpkJj

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

Когда вы нажмете «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».

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

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

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

   mw}jdd'wpkJj

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

mw}jdd'wpkJj
^^

mw ОТМЕТКИ названное местоположение, здесь имя - «w». Я использую 'w' по умолчанию (я думаю об этом как о моем 'рабочем месте. Подойдет любое указанное местоположение из az, если вы согласны.
'W' появится снова через некоторое время, когда мы захотим вернуть курсор в эту строку.

mw}jdd'wpkJj
  ^

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

mw}jdd'wpkJj
   ^

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

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

mw}jdd'wpkJj
    ^^

dd - это команда редактирования «удалить строку», поэтому она удаляет текущую строку, { {1}}, которая представляет собой строку №5 с буквой «kkk». Удаление строки также помещает ее в буфер вставки по умолчанию, который мы будем использовать эксплойт , чтобы вернуть «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
         ^^

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

+---------------
| 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 (левый фигурный, {, подходит для этого) и продолжайте с «ммм». {{1} } Если вы решите, что вам не очень нравится то, как он устроен, удерживайте немного 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
+----------

А как насчет дополнительного символа пробела?
Часть поведения команды Join заключается в том, что она помещает пробел между строками, которые она объединяет.
Если вам не нужен пробел между «xxx kkk», вы можете
добавить команду удаления (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

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

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

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

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

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

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

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

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

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

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

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

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

3
27.01.2020, 20:09

Вы можете сделать это напрямую при редактировании file1 . Введите : , чтобы переключиться в командный режим в vim. Затем введите:

%!paste -d '' - file2
5
27.01.2020, 20:09

Теги

Похожие вопросы