在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复制和粘贴部分会很棒。有什么提示吗?

Answers:


263

如果您使用的是某种UNIX(Linux等),则可以通过column(1)命令作弊和过滤。

:%!column -t

上面的代码将解析字符串文字中的分隔符,这是错误的,因此您可能需要预处理步骤并为此文件指定分隔符,例如:

%!sed 's/","/\&/' | column -t -s '&'

1
很酷的命令,我不知道(过去曾经编写过自定义的perl脚本来执行这种操作)。
hlovdal

24
因为我的文件没有空间,所以不得不使用:%!column -t -s ','。它删除了逗号,因此它们不再是技术上的csv文件。但是将它们布置得很漂亮,这就是我所需要的。
爱德华多

27
大提示!只需添加,它也可用于视觉选择:'<,'>!column -t
freitass 2012年

2
有谁知道使用带引号的列的逗号的解决方案?例如“ 2151 Main ST Houston,TX”
metrix

3
@metrix,这是一个非常笨拙的解决方法:1)将定界符内的空格转换为其他字符,2)然后column按照文章中的描述运行,3)然后将定界符替换回空格。在可视模式下,步骤#1的示例命令为:'<,'>s/"\(\w\+\) \(\w\+\)"/"\1_\2"/g
Luciano 2015年

54

有时我们只想对齐两列。在这种情况下,我们不需要任何插件,可以使用像这样的纯Vim功能:

  1. 选择一个分隔符。在OP的帖子中,这是一个逗号,在我的示例中是=
  2. 在其之前/之后添加空格。我s/=/= ...spaces... /为此在视觉选择中使用。
  3. 找到最长的单词,然后将光标放在其后。
  4. 使用dw和垂直移动删除所有多余的空格。

下面演示了此技术的示例:

例

我发现自己不需要经常调整东西来安装另一个插件,因此这是实现它的首选方式,尤其是不需要太多思考。


4
您是如何制作好的gif的?
Stefano Borini,2015年

1
遗憾,blog.bahraniapps.com / gifcam看起来像是Windows专用工具。
rr-

完成上部的对齐后,如何将光标移到屏幕中间,然后开始对齐下部?
cychoi 2015年

5
之后:s/=/ =/最好使用Ctrl + V选择正确的列,然后使用<<和对其.进行重复。在这里找到它:stackoverflow.com/a/24704379/2152384
pozitron57年

1
或创建一个宏以完成工作@ pozitron57
亚瑟·朱利奥(

24

正如sunny256所建议的那样,该column命令是在Unix / Linux机器上执行此操作的好方法,但是如果您想在纯Vim中执行此操作(以便它也可以在Windows中使用),则最简单的方法是安装Align插件,然后执行以下操作:

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

第一行将逗号上的条目对齐,第二行移动逗号,以使其与先前的值齐平。您可能可以使用AlignCtrl定义一个一次性完成全部功能的自定义映射,但是我永远不记得如何使用它。

编辑

如果您不介意条目之间有两个空格,并且希望在一个命令中执行此操作,则还可以执行以下操作:

:%Align ,\zs

在LaTeX表格中完美工作::'<,'>Align &
Thomas

也可以使用:%Align! lP0 \sl=左对齐,P0=分隔符后的0填充)来完成。
ntd 2014年

8

使用vim宏是一个很好的答案:https : //stackoverflow.com/a/8363786/59384-基本上,您开始记录宏,格式化第一列,停止记录,然后对其余所有行重复该宏。

从该答案中复制/粘贴:

qa0f:w100i <Esc>19|dwjq4@a

请注意100i后面的单个空格,<Esc>的意思是“按转义”-请勿按字面意思键入“ <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)


7

现在,我们还有由junegunn编写的神话般的EasyAlign插件。

从自述文件中演示GIF:


4

您可以使用csv.vim插件。

:%ArrangeColumn

但是,这并不能完全满足您的要求:它将正确调整单元格的内容,而您的值将按小数点或第一个数字对齐。

该插件还有许多其他有用的命令可用于处理CSV文件。





1

这是一个纯Vim脚本答案,没有插件,没有宏:

首先以我的问题的解决方案作为示例可能是最清楚的。我选择了我想影响的代码行,然后使用以下命令(回想一下,从可视模式进入命令模式会自动在“'<,'>”之前加上前缀,因此它作用于可视范围):

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

除了我实际上没有键入“ <0d>”。通过按ctrl-v,然后按要输入的键,可以在命令行上输入不可打印的字符。“ <0d>”是我键入“ ctrl-v enter”后在命令行上呈现的内容。在这里,它是由“普通”命令解析为退出“ /”搜索模式的。然后,光标跳至当前行中的“ value”。

然后,我们只需[D]删除该行的其余部分,跳到第70列(或您需要的情况),然后[P]输入我们刚刚删除的内容。这确实意味着我们必须确定最宽线的宽度,直到搜索为止。如果尚未在状态栏中输入该信息,则可以通过输入普通模式命令“ g ctrl-g”来查看光标的列。另请注意,跳转到不存在的列需要设置“ virtualedit”!

我将:g(lobal)命令的搜索词留空了,因为我们使用了可视块并想影响每一行,但是您可以使用可视选择(和“'<,'>”)删除并放而是搜索字词。或结合视觉选择和搜索词来更精细/更轻松地缩小范围。

这是我最近学到的东西:如果弄乱了复杂的命令模式命令,请用'u'撤消操作(如果它影响了缓冲区),然后按“ q:”进入一个特殊的命令历史记录缓冲区,其作用类似于常规缓冲区。编辑任何行,然后按Enter,更改后的命令将作为新命令输入。如果您不想在第一时间就完美地制定所有内容,则必不可少。


0

我写了python脚本,该脚本允许用户从根本上将vim之外的任何类型的文本都大写。不知道这是否适用于Windows或Mac用户。

columnice.py要点

在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是否会获得新版本) 。无论如何,这对我有用,如果您有任何建议,请发表评论。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.