I have a *.qif file (text file) in which I would like to remove all lines from the second line (not including the header) to a line which contains the characters 'D1/7/2015'. In vim I have tried block selecting from the second line and searching up to a the characters but it doesn't work. What I have tried so far:
Move the cursor to second line then:
v/D1/7/2015
v/D1//7//2015
v/D1///7///2015
None of these seem to work.
You can escape slashes with backslashes:
v/D1\/7\/2015
or tell Vim to parse your pattern with "verymagic" syntax:
v/\vD1/7/2015
See :help \v.
Not exactly what I wanted but it works. I used /D1.7.2015 to get to the line then started visual selection up to the beginning of the file with vgg after which I moved one line down with the cursor then pressed d.
You can delete directly without using the visual selection from the second line to the line containing 'D1/7/2015' by executing the command below:
:2,/D1\/7\/2015/ d
Related
Let's say I have the following three lines and cursor is where ▐ is:
1. This is a slightly longer line.▐I want to delete this and the next line.
2. This is a shorter line
3. This is the third line
I want to delete the rest of the line from the cursor and line 2, so I do vjd, but that leaves my text like:
# This is a slightly longer line.# This is the third line
This is because when selecting text in visual mode, vim selects an additional virtual character at the end of the line. I've played around with virtualedit but that didn't seem to help.
Any clues on how I can get the original behavior that I wanted?
Try three keystrokes - sh-d, sh-j, sh-d
shift-d (delete to end-of-line)
shift-j (merge next line with this)
shift-d (delete the merged, i.e., second line
That will do the trick for you.
That's because if you don't have virtualedit set, vjd will delete everything including the new line character. So you just have to do vjhd instead, to keep the new line intact.
Otherwise with virtualedit=all, I don't face this problem.
I'm reviewing some logs with Java exception spam. The spam is getting is making it hard to see the other errors.
Is is possible in vim to select a block of text, using visual mode. Delete that block every place it occurs in the file.
If vim can't do it, I know silly question, vim can do everything. What other Unix tools might do it?
Sounds like you are looking for the :global command
:g/pattern/d
The :global command takes the form :g/{pat}/{cmd}. Read it as: run command, {cmd}, on every line matching pattern, {pat}.
You can even supply a range to the :delete (:d for short) command. examples:
:,+3d
:,/end_pattern/d
Put this togehter with the :global command and you can accomplish a bunch. e.g. :g/pat/,/end_pat/d
For more help see:
:h :g
:h :d
:h :range
Vim
To delete all matching lines:
:g/regex/d
To only delete the matches themselves:
:%s/regex//g
In either case, you can copy the visual selection to the command line by yanking it and then inserting it with <C-r>". For example, if your cursor (|) is positioned as follows:
hello wo|rld
Then you can select world with viw, yank the selection with y, and then :g/<C-r>"/d.
sed
To delete all matching lines:
$ sed '/regex/d' file
To only delete the matches themselves:
$ sed 's/regex//g' file
grep
To delete all matching lines:
$ grep -v 'regex' file
grep only operates line-wise, so it's not possible to only delete matches within lines.
you can try this in vim
:g/yourText/ d
Based on our discussion in the comments, I guess a "block" means several complete lines. If the first and last lines are distinctive, then the method you gave in the comments should work. (By "distinctive" I mean that there is no danger that these lines occur anywhere else in your log file.)
For simplifications, I would use "ay$ to yank the first line into register a and "by$ to yank the last line into register b instead of using Visual mode. (I was going to suggest "ayy and "byy, but that wold capture the newlines)
To be on the safe side, I would anchor the patterns: /^{text}$/ just in case the log file contains a line like "Note that {text} marks the start of the Java exception." On the command line, I would use <C-R>a and <C-R>b to paste in the contents of the two registers, as you suggested.
:g/^<C-R>a$/,/^<C-R>b$/d
What if the yanked text includes characters with special meaning for search patterns? To be on the really safe side, I would use the \V (very non-magic) modifier and escape any slashes and backslashes:
:g/\V\^<C-R>=escape(#a, '/\')<CR>\$/,/\V\^<C-R>=escape(#b, '/\')<CR>\$/d
Note that <C-R>= puts you on a fresh command line, and you return to the main one with <CR>.
It is too bad that \V was not available when matchit was written. It has to deal with text from the buffer in a search pattern, much like this.
Which is the shortest way to select an entire line without the new line character in VIM?
I know that SHIFT + v selects the entire line, but with new line character.
To do this I go to the line and I press:
^ (puts the cursor at the start of the line)
v (starts the visual select)
$ (selects the entire line including new line character)
Left (unselects the new line character)
I also know that I can create a recording that does such a thing. But I am asking if is there any built-in shortcuts...
Yes, g_ is what you are looking for. g_ is like $, but without the newline character at the end.
Use 0vg_ or ^vg_, depending if you want to copy from the beginning of the line, or the first character on the line, respectively.
No, there is nothing built-in that does the job. That's why people have even created plugins to address the need.
Probably the most popular choice is textobj-line. With textobj-line you get two new text objects, al "a line" and il "inner line". Then,
vil selects the printable contents of the line (like ^vg_),
val selects the entire line contents (like 0v$h).
Both do not include the newline in the selection.
Pretty handy plugin if you ask me. And it works with operators, too.
By request, the installation:
With plain Vim:
Get the latest textobj-user and extract its directories into ~/.vim.
Get the latest textobj-line and extract its directories into ~/.vim.
Generate the help tags :helptags ~/.vim/doc.
With a plugin manager (recommended): just follow the usual installation procedure for your plugin manager, and don't forget to install the textobj-user dependency as well.
0v$
^v$
0vg_
^vg_
$v0
$v^
g_v0
g_v^
all do the job with different conceptions of what a line is (from first column or from first printable character, to last character or to last printable character). You can create a custom mapping if you like.
Note that selecting text is often unnecessary in vim.
Adding on to the answer by #glts, you can replicate the functionality of the textobj-line plugin using only vanilla vim mappings, no plugin installation required.
To do so, add the following to your .vimrc
vnoremap al :<C-U>normal 0v$h<CR>
omap al :normal val<CR>
vnoremap il :<C-U>normal ^vg_<CR>
omap il :normal vil<CR>
The al text object (short for 'a line') includes all characters in a line, but not the terminating newline. This includes all white space.
The il text object (short for 'inside line') goes from the first non-blank character to the last non-blank character.
Commands such as yil,val, and cil work as expected.
If you want to copy line into the buffer, you can use Du, which will delete from the cursor position to the end of line with D, and then revert changes with u. Text will be copied to the buffer without new line symbol.
Redefine $ for visual mode
The unwanted selection of the linefeed in visual mode can be permanently eliminated by adding the following visual mapping to .vimrc:
vnoremap $ g_
This replaces the standard behaviour of $ in visual mode for the move towards right before the linefeed g_.
You can still a mapping to what you want, e.g.:
nnoremap <leader>v 0v$
Another solution $ will be working as you want it to
:vnoremap $ $h
maps your original $ command to new one
Not exactly an answer to your question, but I wonder if you can skip selecting the line and do directly what you want next:
If you want to change the line, just cc
If you want to yank the line, 0y$ (note $ here does not capture the line break because it does not move over it in normal mode, unlike in visual mode)
in VIM, I understand that we can do a yank till the end of line using y$ but if e.g. my text is abcdefg and my cursor is at 'g' and I enter y^ the line will be copy without the g. My idea is to copy the whole line without the line break, any similar action will do.
0y$$ - copy the line without line break and move cursor back to the end
Making it a visual selection and then yanking that includes the character under the cursor:
v0y
If all the characters are indeed together and conform to a "vim sentence", you could use visual selection for the sentence object. A sentence in this case would match abcdefg even if that is not starting at the beginning of a line and it will not include the line ending:
visy
If you want to include trailing whitespace you would use a instead of i (mnemonic for "inside"):
vasy
The only problem with this approach (which may be what you do not want) is that it will not include leading whitespace. So if you have something like:
abcdefg
The selection will not include the leading chunk of whitespace, just abcdefg.
Turns out yanking till end of line is a thing you'll find yourself doing quite often. As such, the following mapping is quite popular.
noremap Y y$
It's so popular, it's even listed under :h Y!
If you use this mapping, the answer to your question would be 0Y
0yg_
is another option.
But visual mode is better:
v0y
v^y
When I open a text file in Notepad, it shows a blank line if there is a carriage return at the end of the last line containing text. However, in Vim it does not show this blank line. Another thing I've noticed is that the Vim editor adds a carriage return to the last line by default (even though it doesn't show it). I can tell, because if I open a file in Notepad that was created in Vim, it shows a blank line at the end of the file.
Anyway, I can live with these two differences, but I'm wondering if there is an option in Vim that allows you to toggle this behaviour.
Thanks
PS - GVim 7.2
[Update]
Would this make sense to be on Server Fault instead?
[Update 2]
I'll rephrase this... I need to know when there is a carriage return at the end of single line file (Notepad shows an extra line with no text, with Vim I cannot tell). This is due to a Progress program that reads a text file (expects a single line, but with a carriage return) and parses the text for some purpose. If there is no carriage return, Progress treats the line as if it is null.
[Workaround Solution]
One way I've found to ensure there is a carriage return (but make sure I don't add a second one) is to make sure I have the end of line write option turned on (:set eol) and then just do a write/save. This will put an end of line in the file if it's not already there. Otherwise, it doesn't add a new one.
:help endofline
explains how you could stop vim from adding an extra newline.
It seems that vim treats newline as a line terminator, while notepad treats it as a line separator: from http://en.wikipedia.org/wiki/Newline
There is also some confusion whether
newlines terminate or separate lines.
If a newline is considered a
separator, there will be no newline
after the last line of a file. The
general convention on most systems is
to add a newline even after the last
line, i.e., to treat newline as a line
terminator. Some programs have
problems processing the last line of a
file if it isn't newline terminated.
Conversely, programs that expect
newline to be used as a separator will
interpret a final newline as starting
a new (empty) line. This can result in
a different line count being reported
for the file, but is otherwise
generally harmless.
If I recall correctly, on unix-y systems a text file must be terminated with a newline.
One useful Vim option is
set list
It will help you see all end of lines characters (and possibly other generally invisible chars). So you will be able to view this last endofline directly in Vim and not only in Notepad.
When you open the file in VIM the status line should say [noeol] after the filename. So that's one indication. As Manni said, you can change this by setting both the endofline option off and the binary option on. You can set this as your default settings in a .vimrc file.