Delete a specific Column in VIM/gvim with out using Visual Block mode

一世执手 提交于 2019-12-22 04:17:07

问题


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


回答1:


In command mode:

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

This uses vim's built-in sed-like search and replace command. Here's the breakdown:

% - for the entire file

s - search for

/^ - the start of line

\([[+|][^+|]\+\) - followed by + or |, followed by any number (\+) of anything that is not + or |. This will get the first column, which we want to keep, so put it in a capture group by surrounding it with \( and \)

[+|][^+|]\+ - followed by + or |, followed by any number (\+) of anything that is not + or |. This will get the second column, which we don't want to keep, so no capture group.

/\1/ - replace everything we matched with the first capture group (which contains the first column). This effectively replaces the first and second column with the contents of the first column.

Like I said, vim's regex are pretty much identical to sed, so you if you look through this tutorial on sed you'll probably pick up a lot of useful stuff for vim as well.

Edit

In response to the OP's request to make this more generally capable of deleting any column:

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

The index inside of the \{\}, now deletes the column indicated. Think of it like an array index (i.e. starts at zero). So \{0\} now deletes the first column, \{1\} deletes the second, and so on.




回答2:


Look, ma: no visual (block) mode !

My pragmatic approach wins would be: look for column anchors (-+-)

/-+-

Now, the column deletion is as simple as

d<C-v>N

(delete, block-wise, to the next occurrence of the column anchor from the end of the document).

Job done.


Fancy options

To account for multiple columns, you'd like to be precise about which column to match

This needs a little extra oomph

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

To see more about this \%22v way to select a virtual column, see

  • Support in vim for specific types of comments



回答3:


I would like to write Mathias Schwarz's comment into an answer because Visual Mode is the natural way for the task, although there is already an accepted answer.

Assuming cursor is in ¶

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

Use normal command Ctrl-V8jf+d to select S1 column and delete it. Explanation:

  • Ctrl-V: Enter in Blockwise Visual Mode.
  • 8j: Eigth is the number of rows of the table, it sets cursor at same column but last line.
  • f+: Move cursor until next + character.
  • d: delete visual selection.

And result is:

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



回答4:


If this is the only content of the file, the simplest way is to use this:

:%normal 22|d32|

IF there is more text in the file, specifies the line interval:

:X,Ynormal 22|d32|

Where X and Y is the line interval, for example: 10,17normal 22|d32|

If you're not familiar with the normal command and with the | "motion" there goes a quick explanation:

  1. The normal command execute the following commands in the normal mode;
  2. The | "motion" moves the cursor to a specified column, so 22| moves the cursor to the 22nd column;

Basically what :X,Ynormal 22|d32|does is to move the cursor to the 22nd column (22|) and deletes everything (d) until the 32nd column (32|) for every line specified by X and Y.




回答5:


Based on patterns of your table, this can be achieved in two simple commands:

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

Where 2 is your column to remove (1 will remove 1st, 3 - 3rd).

This works as below (for each line at once):

  1. Find second corresponding character of the column (2f+ or 2f|).
  2. Delete backwards to the next found character of the column (dF+ or dF|).

Here is command line approach removing 2nd column in-place:

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


来源:https://stackoverflow.com/questions/10514864/delete-a-specific-column-in-vim-gvim-with-out-using-visual-block-mode

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!