3

How can I cut a text file using vim? For example I would like to cut the file up to position 56. So I would like to keep everything from position 1-56, and delete everything from position 57 (including 57) to the end of the line for EVERY line.

Text file:

Web Application - http://sharepoint

Url                                                     CompatibilityLevel
---                                                     ------------------
http://sharepoint                                       15
http://sharepoint/sites/appcatalog                      15
http://sharepoint/sites/devtest                         15
http://sharepoint/sites/publishing                      15

I can get more or less the results I want using awk:

$awk '{print $1}' file

Results:

Web

Url
---
http://sharepoint
http://sharepoint/sites/appcatalog
http://sharepoint/sites/devtest
http://sharepoint/sites/publishing

But say I want to split hairs and really want to keep the title. How can I technically cut this file up to position 56 using vim. Preferably within vim. Meaning I have the file open in vim.

4

There are many ways to do it, here are a few of them:

  1. :%s/\%>56c.//g
  2. :%s/\%57c.*//
  3. :%s/\v^.{56}\zs.*//
  4. :% normal 57|D (this one assumes virtualedit=all or virtualedit=onemore)
  5. Shift-g57|Ctrl-v1Shift-gEndx (this one assumes virtualedit=all)

Edit: Adding the relevant regurgitations from the manual, as requested:

  • For 1. and 2. (:h /\%c):

    \%23c Matches in a specific column.
    \%<23c Matches before a specific column.
    \%>23c Matches after a specific column.
    These three can be used to match specific columns in a buffer or string. The "23" can be any column number. The first column is 1. Actually, the column is the byte number (thus it's not exactly right for multi-byte characters).

  • For 3. (:h \zs):

    \zs Matches at any position, and sets the start of the match there: The next char is the first char of the whole match.

  • For 4. (:h |, :h D, :h :normal, :h :%, :h 'virtualedit'):

    | To screen column [count] in the current line. exclusive motion. Ceci n'est pas une pipe

    ["x]D Delete the characters under the cursor until the end of the line and [count]-1 more lines [into register x]; synonym for "d$".

    :norm[al][!] {commands} Execute Normal mode commands {commands}. This makes it possible to execute Normal mode commands typed on the command-line. {commands} are executed like they are typed.

    % equal to 1,$ (the entire file)

    'virtualedit' A comma separated list of these words:
    block Allow virtual editing in Visual block mode.
    insert Allow virtual editing in Insert mode.
    all Allow virtual editing in all modes.
    onemore Allow the cursor to move just past the end of the line

    Virtual editing means that the cursor can be positioned where there is no actual character. This can be halfway into a tab or beyond the end of the line. Useful for selecting a rectangle in Visual mode and editing a table.

  • For 5. (:h G, :h CTRL-V, :h <End>, :h x):

    G Goto line [count], default last line, on the first non-blank character linewise.

    [count]CTRL-V Start Visual mode blockwise.

    $ or <End> To the end of the line.

    ["x]x Delete [count] characters under and after the cursor [into register x] (not linewise). Does the same as "dl".

  • Please describe how these commands work. – Timothy Martin Mar 13 '17 at 17:20
  • @TimothyMartin Please describe what problems did you encounter understanding how they work. – Satō Katsura Mar 13 '17 at 18:26
  • 1
    Providing solutions without explanation is like giving a man a fish but not teaching him how to fish. While the commands work those who are unfamiliar with using vim commands do not really learn anything. – Timothy Martin Mar 13 '17 at 18:54
  • @TimothyMartin In this particular case, the fishing manual is pretty comprehensive... – Satō Katsura Mar 13 '17 at 18:56
  • @Sato +1 for suggestions. In this case I'm with the OP. It would be helpful if you could add a little explanation... pretty please? – roaima Mar 13 '17 at 19:04
4

Assuming by "position" you mean "column" one could use a regular expression

:%s/^\v(.{56}).*/\1/

Which says from the beginning of the line ^ be more like Perl (\v, magic) match anything . 56 times saving that stuff (the parens), .* to match the rest of the line; replace line with \1 or what saved by the parens.

You could also more or less just call awk, unless filters are illegal for some reason:

:%!awk '{print $1}'
0

In vim, in order to {print $1} for everything except the title, try:

:2,$s/ .*// 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.