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
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
Provided you have grep
on your system, you can use this command:
:!grep -v hello % > file
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.
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.
: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.
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
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.
Example about visual selection and copying: Suppose you want to separate a part:
visual-select it and press ":"
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.