переформатировать в vim для удобного расположения столбцов

У меня есть этот набор данных в файле 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. Любые подсказки?


person Stefano Borini    schedule 04.08.2009    source источник


Ответы (13)


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

:%!column -t

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

%!sed 's/","/\&/' | column -t -s '&'
person sunny256    schedule 04.08.2009
comment
Классная команда, я не знал о ней (в прошлом я написал собственный скрипт на Perl для выполнения такой операции). - person hlovdal; 05.08.2009
comment
Для большего контроля я вставил табуляцию (может быть неиспользуемым символом) в файл, чтобы пометить столбцы с помощью замены, а затем запустил :%!column -t -s ^I для табулирования (Cv, tab вставляет буквальный символ табуляции - ^I ) - person Peter Gibson; 26.01.2011
comment
Поскольку в моих файлах не было места, мне пришлось использовать :%!column -t -s ','. Он удаляет запятые, поэтому они больше не являются файлами csv с технической точки зрения. Но расставляет их красиво, что мне и было нужно. - person Eduardo; 27.02.2012
comment
Отличный совет! Просто добавим, что он работает и для визуального выделения с помощью :'<,'>!column -t - person freitass; 23.08.2012
comment
Команда column -t -s '&' удаляет символ-разделитель, который является проблемой при использовании & в таблице LaTeX в качестве разделителя. - person Thomas; 21.12.2012
comment
также используйте опцию :set nowrap для очень широких файлов, которые выходят за пределы экрана - person Amos Folarin; 25.10.2013
comment
Кто-нибудь знает решение для работы с цитируемыми столбцами с запятыми в столбце? пример 2151 Main ST Хьюстон, Техас - person metrix; 30.12.2013
comment
@ Томас, вы можете сделать что-то подобное, чтобы иметь дело с латексными таблицами... :s/&/;;&/g :!column -t -s ';;' - person equant; 01.03.2015
comment
@metrix, вот очень неуклюжий обходной путь: 1) преобразовать пробелы внутри разделителей в другой символ, 2) затем запустить column, как описано в посте, 3) затем заменить разделители обратно на пробелы. Пример команды в визуальном режиме для шага №1: '<,'>s/"\(\w\+\) \(\w\+\)"/"\1_\2"/g - person Luciano; 11.08.2015
comment
Напоминание для пользователей Windows: column и vim доступны через git bash. - person Leo; 27.02.2017
comment
Потрясающий! (Утверждая очевидное), чтобы свести к минимуму непреднамеренные изменения вашего исходного файла, работайте с копией. - person Victoria Stuart; 07.08.2019

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

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

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

Пример

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

person rr-    schedule 09.02.2015
comment
Как ты сделал такую ​​классную гифку? - person Stefano Borini; 10.02.2015
comment
blog.bahraniapps.com/gifcam, к сожалению, похоже, что это инструмент только для Windows. - person rr-; 10.02.2015
comment
Когда вы закончили выравнивание верхней части, как вы переместили курсор в середину экрана, а затем начали выравнивать нижнюю часть? - person cychoi; 14.07.2015
comment
Я полагаю либо с 15↓, либо с 16G. - person rr-; 14.07.2015
comment
После :s/=/ =/ гораздо лучше использовать Ctrl + V, чтобы выбрать правильный столбец, а затем выровнять его, используя << и ., чтобы повторить. Нашел здесь: stackoverflow.com/a/24704379/2152384 - person pozitron57; 03.01.2017
comment
Или создайте макрос для работы @pozitron57 - person Arthur Julião; 28.05.2017
comment
После одного dw было бы намного быстрее (и менее подвержено ошибкам) ​​использовать повторяющиеся j. или k.. - person Shahbaz; 22.02.2018
comment
Проще всего было бы: '<,'>s/^\(\S*\)/\=printf("%-48s", submatch(1)) Можно расширить его до: '<,'>s/^\(\S*\)\s*=\s*/\=printf("%-48s= ", submatch(1)), и он будет выровнен, даже если строка foo=bar. – Чтобы получить ширину формата, можно было бы сделать: max(map(getline("'<", "'>"), "match(v:val, '=')")) Итак, однострочник: let w = max(map(getline("'<", "'>"), "match(v:val, '=')")) | '<,'>s/^\(\S*\)\s*=\s*/\=printf("%-".w."s= ", submatch(1)) - person user3342816; 21.03.2021

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

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

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

Изменить

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

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

Это отличный ответ с использованием макросов 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)
person zcrar70    schedule 05.06.2014

Кроме того, Tabularize весьма хорош http://vimcasts.org/episodes/aligning-text-with-tabular-vim/

person slf    schedule 06.01.2014
comment
Команда Tabularize (или сокращенно Tab) хорошо работает для файлов csv, разделенных ,, и таблиц уценки, разделенных конвейерами |, но чтобы заставить ее работать с файлами tsv, вам нужно использовать :Tab /, а затем CTRL + V, а затем TAB, как объяснено stackoverflow.com/questions/6951672/ - person Paul Rougieux; 19.03.2021
comment
Шедевр. Архивировать, если сервер выходит из строя: http://web.archive.org/web/20210309173605/http://vimcasts.org/episodes/aligning-text-with-tabular-vim/ - person Eric Leschinski; 30.05.2021

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

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

person rr-    schedule 03.01.2017

Вы можете использовать подключаемый модуль csv.vim.

:%ArrangeColumn

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

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

person Daan    schedule 17.01.2014

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

:set nowrap
:%!column -t

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

person Amos Folarin    schedule 25.10.2013
comment
намного лучше с nowrap. Я включил ваше предложение, спасибо, команда CSV set nowrap | %!столбец -t -s ','`. - person Peruz; 02.01.2020
comment
также обратите внимание на параметр -n, чтобы отключить объединение пустых столбцов. stackoverflow.com/questions/1875305/command-line-csv-viewer< /а> - person Peruz; 03.01.2020

Я просто написал для этой цели tablign. Установить с помощью

pip3 install tablign --user

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

:'<,'>:!tablign

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

person Nico Schlömer    schedule 12.02.2018

Вот ответ на чистом скрипте 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:», чтобы войти в специальный буфер истории команд, который действует так же, как обычный буфер. . Отредактируйте любую строку и нажмите ввод, и измененная команда будет введена как новая команда. Незаменим, если вы не хотите беспокоиться о том, чтобы сформулировать все идеально с первого раза.

person atimholt    schedule 16.06.2019

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

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

person Alice    schedule 05.10.2015

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

columnice.py суть

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

:'<,'>!columnice =

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

person bas080    schedule 06.02.2015

У меня есть это в моем .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 получит новую версию). Во всяком случае, это работает для меня, и прокомментируйте, если у вас есть какие-либо предложения.

person Peruz    schedule 31.01.2020