在 vim 中重新格式化以获得漂亮的列布局

Posted

技术标签:

【中文标题】在 vim 中重新格式化以获得漂亮的列布局【英文标题】:reformat in vim for a nice column layout 【发布时间】:2010-11-16 19:48:18 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

:%!column -t

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

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

【讨论】:

很酷的命令,我不知道(过去编写了自定义 perl 脚本来执行这种操作)。 因为我的文件没有空间,我不得不使用:%!column -t -s ','。它删除了逗号,因此它们不再是技术上的 csv 文件。但是把它们安排得很漂亮,这正是我所需要的。 很棒的提示!只需添加,它也适用于 :'<,'>!column -t 的视觉选择 有谁知道在列中使用带逗号的引用列的解决方案?例如“2151 Main ST Houston, TX” @metrix,这是一个 very 笨拙的解决方法:1)将分隔符内的空格转换为不同的字符,2)然后按照帖子中的描述运行 column,3 ) 然后将分隔符替换回空格。第 1 步在可视模式下的示例命令是:'<,'>s/"\(\w\+\) \(\w\+\)"/"\1_\2"/g【参考方案2】:

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

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

第一行对齐逗号上的条目,第二行移动逗号,使其与前面的值齐平。您也许可以使用AlignCtrl 来定义一个自定义映射,它可以一次性完成所有工作,但我永远不记得如何使用它...

编辑

如果您不介意条目之间有两个空格并且想在一个命令中执行此操作,您也可以这样做:

:%Align ,\zs

【讨论】:

在 LaTeX 表中完美运行::'<,'>Align & 它也可以通过:%Align! lP0 \s 完成(l = 左对齐,P0 = 分隔符后的 0 填充)。【参考方案3】:

如果你有很长的列,禁用默认换行会很方便

:set nowrap :%!列-t

(请注意,在 debian 中,如果要拆分多个相邻的分隔符,您还可以使用 -n 列的更多选项)

【讨论】:

使用 nowrap 会好很多。我包括了你的建议,谢谢'command CSV set nowrap | %!column -t -s ','`。 另外,请注意 -n 选项以禁用空列的合并。 ***.com/questions/1875305/command-line-csv-viewer【参考方案4】:

另外,Tabularize 也不错http://vimcasts.org/episodes/aligning-text-with-tabular-vim/

【讨论】:

Tabularize 命令(或简称Tab)适用于由, 分隔的csv 文件和由管道| 分隔的markdown 表,但要使其适用于tsv 文件,您需要使用:Tab / 后跟CTRL + V 然后TAB,如***.com/questions/6951672/… 解释的那样 杰作。如果服务器出现故障则存档:web.archive.org/web/20210309173605/http://vimcasts.org/episodes/…【参考方案5】:

您可以使用csv.vim 插件。

:%ArrangeColumn

但是,这不会完全按照您的要求进行:它会正确调整单元格的内容,而您的值会按小数点或第一位数字对齐。

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

【讨论】:

【参考方案6】:

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

从该答案复制/粘贴:

qa0f:w100i <Esc>19|dwjq4@a

注意 100i 后面的单个空格, 的意思是“按 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】:

我做了一个用 Perl 编写的 cli 工具。

你可以在这里找到它:https://github.com/bas080/colcise

【讨论】:

【参考方案8】:

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

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

该技术的示例如下所示:

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

【讨论】:

你是怎么做出这么好看的 gif 的? blog.bahraniapps.com/gifcam 不幸的是,它看起来像是一个仅限 Windows 的工具。 上半部分对齐完成后,如何将光标移动到屏幕中间,然后开始对齐下半部分? :s/=/ =/ 之后最好使用Ctrl + V 选择右列,然后使用&lt;&lt;. 对齐以重复。在这里找到它:***.com/a/24704379/2152384 或者创建一个宏来完成工作@pozitron57【参考方案9】:

相当老的问题,但我最近利用了一个出色的 vim 插件,它可以即时或事后(根据您的用例要求)启用表格格式化:

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

【讨论】:

【参考方案10】:

我们现在还拥有由 junegunn 编写的出色的 EasyAlign 插件。

自述文件中的演示 GIF:

【讨论】:

【参考方案11】:

我只是为此目的写了tablign。安装

pip3 install tablign --user

然后在 vim 中简单地标记表格并执行

:'<,'>:!tablign

【讨论】:

【参考方案12】:

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

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

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

除了我没有真正输入“”。您可以在命令行上输入不可打印的字符,方法是按 ctrl-v,然后按您要键入的键。 “”是我输入“ctrl-v enter”后在命令行上呈现的内容。在这里,它被“普通”命令解析为退出“/”搜索模式。然后光标跳转到当前行的“value”。

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

我将 :g(lobal) 命令的搜索词留空,因为我们使用了视觉块并希望影响每一行,但您可以使用视觉选择(以及“'” ) 并在那里放置一个搜索词。或者结合视觉选择和搜索词来更精细/更轻松地缩小范围。

这是我最近学到的东西:如果你搞砸了一个复杂的命令模式命令,用 'u' 撤消(如果它影响了缓冲区),然后按“q:”进入一个特殊的命令历史缓冲区,它的作用很像常规缓冲区。编辑任意行并按回车键,更改的命令将作为新命令输入。如果您不想在第一次完美地制定所有内容时感到压力,那么这是必不可少的。

【讨论】:

【参考方案13】:

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

【讨论】:

以上是关于在 vim 中重新格式化以获得漂亮的列布局的主要内容,如果未能解决你的问题,请参考以下文章

shell脚本的漂亮打印

更漂亮的将 if / else 重新格式化为单行

在 Vim 中(重新)格式化 PHP 代码

保存时更漂亮的 VSCODE 重新格式化已停止工作

vim 如何重新格式化 `gq` 避免触及 TeX 逐字部分?

如何重新格式化字符串以不包括 Python 中的重音字母? [复制]