переформатировать в vim для хорошей разметки столбцов

126

У меня есть этот набор данных в файле csv

1.33570301776, 3.61194e-06, 7.24503e-06, -9.91572e-06, 1.25098e-05, 0.0102828, 0.010352, 0.0102677, 0.0103789, 0.00161604, 0.00167978, 0.00159998, 0.00182596, 0.0019804, 0.0133687, 0.010329, 0.00163437, 0.00191202, 0.0134425 
1.34538754675, 3.3689e-06, 9.86066e-06, -9.12075e-06, 1.18058e-05, 0.00334344, 0.00342207, 0.00332897, 0.00345504, 0.00165532, 0.00170412, 0.00164234, 0.00441903, 0.00459294, 0.00449357, 0.00339737, 0.00166596, 0.00451926, 0.00455153
1.34808186291, -1.99011e-06, 6.53026e-06, -1.18909e-05, 9.52337e-06, 0.00158065, 0.00166529, 0.0015657, 0.0017022, 0.000740644, 0.00078635, 0.000730052, 0.00219736, 0.00238191, 0.00212762, 0.00163783, 0.000750669, 0.00230171, 0.00217917

Как видите, числа отформатированы по-другому и не выровнены. Есть ли в vim способ быстро выровнять столбцы должным образом, чтобы результат был таким

1.33570301776,  3.61194e-06, 7.24503e-06, -9.91572e-06, 1.25098e-05, 0.0102828,  0.010352,   0.0102677,  0.0103789, 0.00161604, 0.00167978, 0.00159998, 0.00182596, 0.0019804,  0.0133687,  0.010329,   0.00163437, 0.00191202, 0.0134425 
1.34538754675,  3.3689e-06,  9.86066e-06, -9.12075e-06, 1.18058e-05, 0.00334344, 0.00342207, 0.00332897, 0.00345504,0.00165532, 0.00170412, 0.00164234, 0.00441903, 0.00459294, 0.00449357, 0.00339737, 0.00166596, 0.00451926, 0.00455153
1.34808186291, -1.99011e-06, 6.53026e-06, -1.18909e-05, 9.52337e-06, 0.00158065, 0.00166529, 0.0015657,  0.0017022, 0.000740644,0.00078635, 0.000730052,0.00219736, 0.00238191, 0.00212762, 0.00163783, 0.000750669,0.00230171, 0.00217917

Было бы здорово копировать и вставлять разделы с помощью ctrl-v. Есть подсказки?

Стефано Борини
источник

Ответы:

263

Если вы используете какую-то UNIX (Linux и т. Д.), Вы можете обмануть и отфильтровать ее с помощью команды column (1).

:%!column -t

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

%!sed 's/","/\&/' | column -t -s '&'
sunny256
источник
1
Классная команда, я не знал об этом (в прошлом я писал собственный сценарий perl для выполнения таких операций).
hlovdal 04
24
Потому что в моих файлах не было места, которое мне пришлось использовать :%!column -t -s ','. Он удаляет запятые, поэтому они больше не являются техническими CSV-файлами. Но красиво их расставляет, а мне это и нужно было.
Эдуардо
27
Отличный совет! Просто добавляю, он работает и для визуального выбора с:'<,'>!column -t
freitass
2
Кто-нибудь знает решение для работы с цитируемыми столбцами с запятыми в столбце? пример "2151 Main ST Houston, TX"
metrix
3
@metrix, вот очень неуклюжий обходной путь: 1) преобразовать пробелы внутри разделителей в другой символ, 2) затем запустить, columnкак описано в сообщении, 3) затем заменить ваши разделители обратно на пробелы. Пример команды в визуальном режиме для шага № 1:'<,'>s/"\(\w\+\) \(\w\+\)"/"\1_\2"/g
Лучано,
54

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

  1. Выберите разделитель. В сообщении OP это запятая, в моем примере это =.
  2. Добавьте пробелы до / после него. Я использую s/=/= ...spaces... /для этого визуальный отбор.
  3. Найдите самое длинное слово и поместите курсор после него.
  4. Удалите все лишние пробелы, используя dwи вертикальное движение.

Пример этой техники показан ниже:

пример

Мне не нужно часто согласовывать вещи, чтобы установить другой плагин, поэтому я предпочел это сделать, особенно потому, что это не требует много размышлений.

rr-
источник
4
Как ты сделал этот красивый гиф?
Стефано Борини
1
blog.bahraniapps.com/gifcam, к сожалению, похоже, что это инструмент только для Windows.
rr-
Когда вы закончили выравнивание верхней части, как вы переместили курсор в середину экрана, а затем начали выравнивать нижнюю часть?
cychoi
5
После :s/=/ =/гораздо лучше использовать Ctrl + Vдля выбора правого столбца, а затем выровнять его с помощью <<и .для повторения. Нашел здесь: stackoverflow.com/a/24704379/2152384
pozitron57 03
1
Или создайте макрос для выполнения работы @ pozitron57
Arthur Julião
24

Как предположил sunny256, columnкоманда - отличный способ сделать это на машинах Unix / Linux, но если вы хотите сделать это в чистом Vim (чтобы его можно было использовать и в Windows), самый простой способ - установить Align плагин, а затем выполните:

:%Align ,
:%s/\(\s\+\),\s/,\1/g

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

редактировать

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

:%Align ,\zs
Dral
источник
Отлично работает в таблице LaTeX::'<,'>Align &
Thomas
Это также можно сделать с помощью :%Align! lP0 \s( l= выровнено по левому краю, P0= 0 заполнение после разделителя).
ntd
8

Это отличный ответ с использованием макросов vim: https://stackoverflow.com/a/8363786/59384 - в основном вы начинаете записывать макрос, форматируете первый столбец, останавливаете запись, а затем повторяете макрос для всех оставшихся строк.

Скопируйте / вставьте из этого ответа:

qa0f:w100i <Esc>19|dwjq4@a

Обратите внимание на один пробел после 100i, а <Esc> означает «нажмите escape» - не вводите «<Esc>» буквально.

Перевод:

qa         -- record macro in hotkey a
0          -- go to beginning of line
f:         -- go to first : symbol
w          -- go to next non-space character after the symbol
100i <Esc> -- insert 100 spaces
19|        -- go to 19th column (value 19 figured out manually)
dw         -- delete spaces until : symbol
j          -- go to next line
q          -- stop recording macro
4@a        -- run the macro 4 times (for the remaining 4 lines)
zcrar70
источник
7

Теперь у нас также есть великолепный плагин EasyAlign , написанный junegunn.

Демонстрационный GIF из README:

rr-
источник
4

Вы можете использовать плагин csv.vim .

:%ArrangeColumn

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

В плагине есть много других полезных команд для работы с CSV-файлами.

Даан
источник
3

также, если у вас очень длинные столбцы, может быть удобно отключить перенос по умолчанию

: установить nowrap
:%! столбец -t

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

Амос Фоларин
источник
намного лучше с nowrap. Я включил ваше предложение, спасибо, команда CSV set nowrap | %! столбец -t -s ',' `.
Перуз
также обратите внимание на параметр -n для отключения слияния пустых столбцов. stackoverflow.com/questions/1875305/command-line-csv-viewer
Перуц
3

Я просто для этого написал таблин . Установить с помощью

pip3 install tablign --user

Затем просто отметьте таблицу в vim и выполните

:'<,'>:!tablign

введите описание изображения здесь

Нико Шлёмер
источник
1

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

https://github.com/dhruvasagar/vim-table-mode

Алиса
источник
1

Вот чистый ответ сценария Vim, без плагинов и макросов:

Возможно, будет наиболее очевидным начать с примера решения моей проблемы. Я выбрал строки кода, на которые хотел повлиять, затем использовал следующую команду (напомним, что при входе в командный режим из визуального режима автоматически добавляется «'<,'>», поэтому он действует в визуальном диапазоне):

:'<,'>g``normal / "value<0d>D70|P`

За исключением того, что на самом деле я НЕ набирал «<0d>». Вы можете ввести непечатаемые символы в командной строке, нажав ctrl-v, а затем клавишу, которую вы хотите ввести. «<0d>» - это то, что отображается в командной строке после того, как я набрал ctrl-v enter. Здесь он обрабатывается «нормальной» командой как выход из режима поиска «/». Затем курсор переместится к «значению» в текущей строке.

Затем мы просто [D] удаляем оставшуюся часть строки, переходим к столбцу 70 (или тому, что вам нужно в вашем случае), и [P] удаляем то, что мы только что удалили. Это означает, что мы должны определить ширину самой широкой линии вплоть до нашего поиска. Если вы не поместили эту информацию в строку состояния, вы можете увидеть столбец курсора, введя команду обычного режима 'g ctrl-g'. Также обратите внимание, что для перехода к несуществующему столбцу требуется параметр virtualedit!

Я оставил поисковый запрос для команды: g (lobal) пустым, поскольку мы использовали визуальный блок и хотели воздействовать на каждую строку, но вы можете отказаться от использования визуального выделения (и «'<,'>») и поставить вместо этого введите поисковый запрос. Или скомбинируйте визуальный выбор и поисковый запрос, чтобы сузить / упростить задачу.

Вот кое-что, что я недавно узнал: если вы испортили сложную команду командного режима, отмените с помощью 'u' (если это повлияло на буфер), затем нажмите «q:», чтобы войти в специальный буфер истории команд, который действует так же, как обычный буфер. , Отредактируйте любую строку и нажмите Enter, и измененная команда будет введена как новая команда. Незаменим, если вы не хотите напрягаться из-за того, что сформулировали все идеально с первого раза.

atimholt
источник
0

Я написал скрипт на Python, который позволяет пользователям разбивать на столбцы любой тип текста даже за пределами vim. Не уверен, будет ли это работать для пользователей Windows или Mac.

columnice.py gist

Использование в vim.

:'<,'>!columnice =

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

Бассим Хуис
источник
0

У меня это есть в моем .vimrc.

command! CSV set nowrap | %s/,/,|/g | %!column -n -t -s "|" 

Это выравнивает столбцы с сохранением запятой, которая может понадобиться позже для правильного чтения. Например, с Python Pandas read_csv(..., skipinitialspace=True)спасибо, ребята, Pandas за эту умную опцию, в противном случае в vim %s/,\s\+/,/g. Это может быть проще, если у вас columnесть опция --output-separator, я думаю, у меня нет, и я не уверен, почему (моя страница руководства для столбца говорит 2004, на ubuntu 18.04, не уверен, что ubuntu получит новую версию) , В любом случае, это работает для меня, и прокомментируйте, если у вас есть какие-либо предложения.

Peruz
источник