Linewise Selection in VIM

How can I select all lines that do not contain the word "hello" in VIM? I need it yanked and then saved to a file. How can I do it? I am looking for something like:

:v/!(hello) > file

Upvotes: 3

Views: 1133

Answers (10)

Joel W. Shea
Joel W. Shea

Reputation:

Pretty straight forward;

:v/hello/ |redir >> file

Upvotes: 1

Mykola Golubyev
Mykola Golubyev

Reputation: 59804

After Vim command

:let @a='' | g!/hello/normal "Ayy

you will have all the lines that doesn't have 'hello' in the register 'a'. You can paste its value with "ap normal command or put this value to system clipboard with

:let @*=@a

And you can use then 'Ctrl+V' on Windows or 'Cmd+V' on Mac Os or 'middle mouse click' on Linux to paste the text.

Brief description of the magic:

@a is a Vim variable that is bound to value stored in the 'a' register.
"ap, "bp, "cp, .. is the key combination in the Vim normal mode to past a value from the specific register.
@* is a Vim variable that is bound to the System clipboard.
let @* = @a put value from the register 'a' to the System clipboard.

Add this to your .vimrc or create file withing plugin dir.

function s:copy_unmathced_lines(pattern)
   let result_lines = []

   for line in getline(1, '$')
      if line !~ a:pattern
         call add(result_lines, line)
      endif
   endfor

   let @* = join(result_lines, "\n")
endfunction

command -nargs=1 CopyUnmatchedLines call s:copy_unmathced_lines(<q-args>)

Use case is simple:

CopyUnmatchedLines hello

and then just use paste command in any editor.

Upvotes: 0

Example about visual selection and copying: Suppose you want to separate a part:

  1. visual-select it and press ":"

  2. then use the command:

    :'<,'> ! > ../new_file_in_a_subdirectory

Error: the colours will be copied to the file, and it is not actually coping rather cut-and-paste.

Upvotes: 0

A practical Example with Blixtor's snippet: Email friends lost with ":verbosefile".

I. open manual ":e /tmp/new_file" and ":h verbosefile", then let's copy-cat blixtor's tip:

:redir > /tmp/verbosefile_instructions
:g/verbosefile/
:redir END

II. affirm that you follow the standard rules about the legth of your emails, and source the standard greetings:

:match ErrorMsg /\%>73v.\+/
:so /bin/greetings.vim

III. Send the file with Mutt.

Upvotes: 0

bfabry
bfabry

Reputation: 1904

:g!/hello/ yank A

The lines are now stored in register a, to paste them do "ap

Edit: Can be abbreviated to

:g!/hello/y A

For those interested in what this means to vim:

:g = global search
! = negation of boolean test that follows
/hello/ = regular expression to match "hello"
y = command to perform upon each matched line, in this case "yank"
A = register argument to "yank" command. In this case register 'a' but in the form of upper case meaning append to the register rather than replace.

Upvotes: 12

sjh
sjh

Reputation: 2266

fgm's answer was nearly there

:v will select lines that do NOT match

so the following will append lines not containing "hello" to a file called eee, creating it if required.

:v/hello/ . w!>>eee

Upvotes: 4

user55400
user55400

Reputation: 4029

An alternative I did not see mentioned so far, is redirecton.

So for your case this would be

:redir > file
:g!/hello/
:redir END

See also

:help redir
:help verbosefile

Upvotes: 6

Fritz G. Mehner
Fritz G. Mehner

Reputation: 17188

Select and write to a new file:

:g/hello/ . w!>> file 

Upvotes: 1

d.hoeffer
d.hoeffer

Reputation: 602

I usually do this with some variation of

:g/hello/d

i.e. delete everything containing "hello", then select, yank, or whatever needs to be done, and finally revert back hitting u. I find this is less mentally taxing then building command line pipes.

Upvotes: 6

too much php
too much php

Reputation: 90978

Provided you have grep on your system, you can use this command:

:!grep -v hello % > file

Upvotes: 9

Related Questions