Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用可视块模式删除VIM/gvim中不带out的特定列_Vim - Fatal编程技术网

使用可视块模式删除VIM/gvim中不带out的特定列

使用可视块模式删除VIM/gvim中不带out的特定列,vim,Vim,示例输入文件 +--------------------+---------+--------- | Name | S1 | S2 +--------------------+---------+--------- | A | -4.703 | -2.378 | B | -3283.2 | -3204.5 | C | 8779 | 73

示例输入文件

+--------------------+---------+---------
|           Name     |   S1    |    S2
+--------------------+---------+---------
|           A        | -4.703  | -2.378  
|           B        | -3283.2 | -3204.5 
|           C        |  8779   |  7302   
|           D        |  22078  |  18018  
+--------------------+---------+---------
需要移除S1柱,即

期望输出

+--------------------+---------
|           Name     |   S2    
+--------------------+---------
|           A        | -2.378    
|           B        | -3205.5  
|           C        |  7302      
|           D        |  18018    
+--------------------+---------
有人能帮忙吗

在命令模式下感谢您:

:%s/^\([[+|][^+|]\+\)[+|][^+|]\+/\1/
这使用了vim内置的sed-like搜索和替换命令。以下是分类:

%
-用于整个文件

s
-搜索

/^
-行的开始

\([[+\][^+\\+]\+\)
-后跟
+
\
,后跟任何非
+
\
的数字(
\+
)。这将获得我们想要保留的第一列,因此将其放在捕获组中,并用
\(
>)

[+\124;][^+\ 124;]\+
-后跟
+
\
,后跟任何非
+
\+
的数字(
\+
)。这将得到第二列,我们不想保留它,因此没有捕获组

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

正如我所说,vim的正则表达式与sed几乎相同,因此如果您仔细查看,可能也会发现许多对vim有用的东西

编辑

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

\{\}
中的索引现在删除指定的列。将其视为数组索引(即从零开始)。因此
\{0\}
现在删除第一列
\{1\}
删除第二个,依此类推。

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

假设光标位于»

+--------------------+¶--------+--------- | Name | S1 | S2 +--------------------+---------+--------- | A | -4.703 | -2.378 | B | -3283.2 | -3204.5 | C | 8779 | 7302 | D | 22078 | 18018 +--------------------+---------+--------- 看,马:没有视觉(块)模式! 我的务实方法是:寻找专栏锚(
-+-

现在,列删除操作非常简单

d<C-v>N
dN
(按块删除,直到从文档末尾开始的列定位的下一次出现)

工作完成了。
别致的选择 要考虑多个列,您需要精确地确定要匹配的列

这需要一点额外的魅力

0f+
:exec'/\%'.col('.').“v\v[+|]”
输入
NC vN
t+d

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


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

:%normal 22|d32|
如果文件中有更多文本,请指定行间隔:

:X,Ynormal 22|d32|
其中X和Y是线间隔,例如:
10,17正常22 | d32 |

如果您不熟悉普通命令和|“运动”,可以快速解释:

  • normal
    命令在normal模式下执行以下命令
  • |“运动”将光标移动到指定列,因此
    22 |
    将光标移动到第22列

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

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

    :%norm 2f+dF+
    :%norm 2f|dF|
    
    其中,
    2
    是要删除的列(
    1
    将首先删除,
    3
    -3)

    其工作原理如下(一次针对每条线路):

  • Find列的第二个对应字符(
    2f+
    2f |
  • D向后删除列的下一个found字符(
    dF+
    dF |
  • 以下是在适当位置移除第二列的命令行方法:

    $ ex +'%norm 2f+dF+' +'%norm 2f|dF|' -scx cols2
    

    为什么不使用视觉块模式呢?这正是该模式的用途…我正想这样做,作为vim脚本的一部分!!所以,谢谢:)你能解释一下吗?我刚刚在我的回答中添加了一行,问你这个问题。一秒钟。太棒了!很好的解释!!像Wise一样,你能解释删除S2列并让S1列出现吗!!很抱歉给您带来麻烦,请考虑将该通用版本简化为
    %s/^\v(+++){2}.{-}[+}]/\1/
    。尽管我在回答中仍然更喜欢/-+-regex:),但我已经简化了方法,并提供了更精确的寻址方式(而不是任意单元8j)在精彩中。这个答案值得一个+1Hah。谢谢。我刚刚编辑了我的描述,以明确我在第一部分中没有使用视觉块模式。对投反对票的人说:你想解释一下这个答案有哪些地方可以改进吗?
    :X,Ynormal 22|d32|
    
    :%norm 2f+dF+
    :%norm 2f|dF|
    
    $ ex +'%norm 2f+dF+' +'%norm 2f|dF|' -scx cols2