在vim中,在Windows机器中(无法访问" unix"类似命令这样的命令列)我想重新格式化这段代码以使其更具可读性:
COLUMN KEY_ID FORMAT 9999999999
COLUMN VALUE_1 FORMAT 99
COLUMN VALUE_2 FORMAT 99
COLUMN VALUE_3 FORMAT 999
COLUMN VALUE_4 FORMAT 999
我希望尽可能减少使用此命令:
COLUMN KEY_ID FORMAT 9999999999
COLUMN VALUE_1 FORMAT 99
COLUMN VALUE_2 FORMAT 99
COLUMN VALUE_3 FORMAT 999
COLUMN VALUE_4 FORMAT 999
请注意,这只是一个摘录,因为还有更多行我必须这样做。
答案 0 :(得分:4)
您可以使用以下命令:
:%s/\w\zs\s*\zeFORMAT/^I
该模式将匹配FORMAT
与前一个单词结尾之间的空格,并将其替换为标签:
\w Any 'word' character
\zs Start the matching
\s* Any number of whitespace
\ze End the matching
FORMAT The actual word format
\zs
和\ze
仅允许在空白处应用替换,请参阅::h /\zs
和:h /\ze
请注意^I
应插入 ctrl + v 标签
@SatoKatsura推荐的tabular plugin也是一个很好的方法。
你也可以概括一下。我们假设你有以下文件:
COLUMN KEY_ID FORMAT 9999999999
COLUMN VALUE_1 FOO 99
COLUMN VALUE_2 BAR 99
您可以使用此命令:
:%s/^\(\w*\s\)\{1}\w*\zs\s*\ze/
模式可以像这样详细说明:
^ Match the beginning of the line
\(\w*\s\)\{1} One occurrence of the pattern \w*\s i.e. one column
\w* Another column
\zs\s*\ze The whitespaces after the previous column
您可以更改\{1}
的值以在下一列上应用命令。
编辑回答@aturegano评论,这是将列与另一列对齐的方法:
%s/^\(\w*\s\)\{1}\w*\zs\s*\ze/\=repeat(' ', 30-matchstrpos(getline('.'), submatch(0))[1])
我们的想法仍然是匹配必须对齐的空格,在替换命令的第二部分,我们使用子替换表达式(参见:h sub-replace-expression
)。
这允许我们使用来自替换部分的命令,可以这样解释:
\= Interpret the next characters as a command
repeat(' ', XX) Replace the match with XX whitespaces
XX is decomposed like this:
30- 30 less the next expression
matchstrpos()[1] Returns the columns where the second argument appears in the first one
getline('.') The current line (i.e. the one containing the match
submatch(0) The matched string
[1] Necessary since matchstrpos() returns a list:
[matchedString, StartPosition, EndPosition]
and we are looking for the second value.
然后,您只需将30替换为要移动下一列的列。
答案 1 :(得分:2)
对于对齐,有三个众所周知的插件:
答案 2 :(得分:2)
按要求发布答案:
:g/^COLUMN / s/.*/\=call('printf', ['%s %-30s %s %s'] + split(submatch(0)))/
说明:
g/^COLUMN /
- 将以下命令应用于与/^COLUMN /
匹配的行(参见:h :global
)\=
- 替换为评估表达式的结果,而不是使用固定字符串(参见:h s/\=
)submatch(0)
- 匹配的行split(...)
- 将行拆分为单词printf(...)
- 格式化call(...)
- 我们希望printf('%s %-30s %s %s', list)
,但printf()
不会将“真实”列表作为参数,因此我们必须以{{1}展开列表(参见call(...)
)。答案 3 :(得分:0)
又一个解决方案:
:%s/ \{2,}/ /g
此解决方案并不完美,因为结果将在第一行上有额外的单个空格。要解决此问题:
:%s/\%>15c \{2,}/ /g
模式说明:
%>15c\s\{2,}
%>15c Matches only after column 15
\s\{2,} Matches two or more white spaces