8

Sample Input File

+--------------------+---------+---------
|           Name     |   S1    |    S2
+--------------------+---------+---------
|           A        | -4.703  | -2.378  
|           B        | -3283.2 | -3204.5 
|           C        |  8779   |  7302   
|           D        |  22078  |  18018  
+--------------------+---------+---------

It is required to remove the S1 Column, i.e

Desired Output

+--------------------+---------
|           Name     |   S2    
+--------------------+---------
|           A        | -2.378    
|           B        | -3205.5  
|           C        |  7302      
|           D        |  18018    
+--------------------+---------

Can anyone help with this

thanks

4

5 回答 5

4

看,ma:没有视觉(块)模式

我的务实方法获胜将是:寻找列锚(-+-

/-+-

现在,列删除很简单

d<C-v>N

(从文档末尾逐块删除到下一个出现的列锚点)。

任务完成。


花哨的选择

要考虑多个列,您希望准确确定要匹配的列

这需要一点额外的魅力

0f+
:exec '/\%' . col('.') . 'v\v[+|]'Enter
NC-vN
t+d

要了解有关这种\%22v选择虚拟列的方式的更多信息,请参阅

于 2012-05-09T16:05:32.067 回答
3

我想将Mathias Schwarz的评论写成答案,因为视觉模式是该任务的自然方式,尽管已经有一个公认的答案。

假设光标在 ¶

+--------------------+¶--------+---------
| 姓名 | S1 | S2  
+--------------------+---------+---------
| 一个 | -4.703 | -2.378  
| 乙| -3283.2 | -3204.5
| C | 8779 | 7302   
| D | 22078 | 18018  
+--------------------+---------+---------

使用普通命令Ctrl-V8jf+d选择S1列并将其删除。解释:

  • Ctrl-V:进入 Blockwise 可视模式。
  • 8j : Eigth 是表格的行数,它将光标设置在同一列但最后一行。
  • f+:将光标移动到下一个+字符。
  • d:删除视觉选择。

结果是:

+--------------------+---------
|           Name     |    S2
+--------------------+---------
|           A        | -2.378  
|           B        | -3204.5 
|           C        |  7302   
|           D        |  18018  
+--------------------+---------
于 2012-05-09T12:50:09.147 回答
3

在命令模式下:

:%s/^\([[+|][^+|]\+\)[+|][^+|]\+/\1/

这使用 vim 内置的类似 sed 的搜索和替换命令。这是细分:

%- 对于整个文件

s- 搜索

/^- 线的开始

\([[+|][^+|]\+\)- 后跟+|,后跟任意数量 ( \+) 的任何 +|。这将获得我们想要保留的第一列,因此将其放在捕获组中,用\(和包围它\)

[+|][^+|]\+- 后跟+|,后跟任意数量 ( \+) 的任何 +|。这将得到第二列,我们不想保留,所以没有捕获组。

/\1/- 用第一个捕获组(包含第一列)替换我们匹配的所有内容。这有效地用第一列的内容替换了第一列和第二列。

就像我说的,vim 的正则表达式与 sed 几乎相同,所以如果你阅读这个关于 sed 的教程,你可能也会学到很多对 vim 有用的东西。

编辑

为了响应 OP 的要求,使其更普遍地能够删除任何列:

:%s/^\(\([[+|][^+|]\+\)\{1\}\)[+|][^+|]\+/\1/

, 内的索引\{\}现在删除指示的列。把它想象成一个数组索引(即从零开始)。所以\{0\}现在删除第一列,\{1\}删除第二列,依此类推。

于 2012-05-09T11:14:30.273 回答
2

如果这是文件的唯一内容,最简单的方法是使用:

:%normal 22|d32|

如果文件中有更多文本,则指定行间隔:

:X,Ynormal 22|d32|

其中 X 和 Y 是行间隔,例如:10,17normal 22|d32|

如果您不熟悉普通命令和 | “运动”有一个快速的解释:

  1. normal命令在正常模式下执行以下命令;
  2. 该| "motion" 将光标移动到指定列,因此22|将光标移动到第 22 列;

基本上:X,Ynormal 22|d32|所做的是将光标移动到第 22 列 ( 22|) 并删除所有 ( ) 直到由 X 和 Y 指定的每一行d的第 32 列 ( 32|)。

于 2012-05-09T17:08:43.123 回答
0

根据您的表格模式,这可以通过两个简单的命令来实现:

:%norm 2f+dF+
:%norm 2f|dF|

2您要删除的列在哪里(1将删除第 1 个,3-第 3 个)。

这工作如下(一次为每一行):

  1. 查找列的第二个对应字符 (2f+2f|)。
  2. D向后删除到该列的下一个找到的字符(dF+dF|)。

这是就地删除第二列的命令行方法:

$ ex +'%norm 2f+dF+' +'%norm 2f|dF|' -scx cols2
于 2015-10-18T13:31:27.733 回答