How to add a line after every few lines in vim - vim

I wanted to add a line after every 3 lines in a file (having about 1000 lines) using vim editor. Can someone help me out?
Thanks,
Alisha

there is a vim-specific regular expression to do that
:%s/.*\n.*\n.*\n/\0\r/g
%s is vim ex command to substitute in the whole file
.*\n is a line including the end of line
\0 is the entire matched expression
\r vim way to say add a new line (not \n as one would expect)
Edit: if you want anything else than a new line, just put the text in front of the \r (properly regex escaped, if it contains some regex characters)

You can use a macro. The complete process looks like:
qq " start recording to register q (you could use any register from a to z)
o " insert an empty line below cursor
<Esc> " switch to normal mode
jjj " move the cursor 3 lines downward
q " stop recording
Then just move to the start line and type 1000#q to execute your macro 1000 times.

" insert a blank line every 3 lines
:%s/\v(.*\n){3}/&\r
: .............. command
% .............. whole file
s .............. replace
/ .............. start pattern that we will replace
\v ............. very magic mode, see :h very-magic
(.*\n) ......... everything including the line break
{3} ............ quantifier
/ .............. start new pattern to replace
& .............. corresponds to the pattern sought in (.*\n)
\r ............. add line break
source: http://www.rayninfo.co.uk/vimtips.html

I would do this:
:%s/^/\=(line(".")%4==0?"\n":"")/g
this works if your requirement changed to " *add a new blank line every 700 line*s" :) you just change the "4"
P.S. if I need do this, I won't do it in vim. sed, awk, could do it much simpler.

Related

How to use Vim to do multiple line edit

I have text like this:
w ky,
wyz,
wyy,
wj,
w w,
and I want to change it to this:
"w ky",
"wyz",
"wyy",
"wj",
"w w",
I do it now using:
record a macro to insert double quota in one line, then go to next line qa0wi"$i"j
then just type 4#a
Yes, it works, but is there an easier way to do this?
There is an easier way. You can use the norm command. I would recommend this:
Visually select all of the lines
Type
:norm I"<C-v><esc>$i"<cr>
When you actually type this (before hitting enter), the text that should be shown in your command line is:
:'<,'>norm I"^[$i"
The norm command tells vim to simulate a set of normal mode keystrokes on certain lines. In this case, the command is:
:'<,'> " On every line in the visual selection:
norm " Do the following as if typed in normal mode:
I"<esc>$i" " Insert an '"', escape, then insert a '"' at the end (before the comma)
You can also do this without using a visual selection, by typing <n>:norm ..., and the command will apply the current n lines. (the current line and the next n-1 lines)
Doing a "very magic search \v" we can search...
\v(\w ?\w+),
\v ........... starts very magic search mode
( ........... starts group one
\w ........... any word
? ........... optional space
+ ........... one or more
) ........... ends group one
After testing the search we can pass into our command or
use the last search by placing two slashes on the search pattern
%s/\v(\w ?\w+),/"\1",/g
%s//"\1",/g
everything matched on group one can be referred by \1.
Do a basic multi-line edit at the front then do a string replace on , with ",.

Vim: delete empty lines around cursor

Suppose I'm editing the following document (* = cursor):
Lions
Tigers
Kittens
Puppies
*
Humans
What sequence can I use to delete the surrounding white space so that I'm left with:
Lions
Tigers
Kittens
Puppies
*
Humans
Note: I'm looking for an answer that handles any number of empty lines, not just this exact case.
EDIT 1: Line numbers are unknown and I only want to effect the span my cursor is in.
EDIT 2: Edited example to show I need to preserve leading whitespace on edges
Thanks
Easy. In normal mode, dipO<Esc> should do it.
Explanation:
dip on a blank line deletes it and all adjacent blank lines.
O<Esc> opens a new empty line, then goes back to normal mode.
Even more concise, cip<Esc> would roll these two steps into one, as suggested by #Lorkenpeist.
A possible solution is to use the :join command with a range:
:?.?+1,/./-1join!
Explanation:
[range]join! will join together a [range] of lines. The ! means with out inserting any extra space.
The starting point is to search backwards to the first character then down 1 line, ?.?+1
As the 1 in +1 can be assumed this can be abbreviated ?.?+
The ending point is to search forwards to the next character then up 1 line, /./-1
Same as before the 1 can be assumed so, /./-
As we are using the same pattern only searching forward the pattern can be omitted. //-
The command :join can be shorted to just :j
Final shortened command:
:?.?+,//-j!
Here are some related commands that might be handy:
1) to delete all empty lines:
:g/^$/d
:v/./d
2) Squeeze all empty lines into just 1 empty line:
:v/./,//-j
For more help see:
:h :j
:h [range]
:h :g
:h :v
Short Answer: ()V)kc<esc>
In normal mode, if you type () your cursor will move to the first blank line. ( moves the cursor to the beginning of the previous block of non-blank lines, and ) moves the cursor to the end (specifically, to the first blank line after said block). Then a simple d) will delete all text until the beginning of the next non-blank line. So the complete sequence is ()d).
EDIT: You're right, that deletes the whitespace at the beginning of the next non-blank line. Instead of d) try V)kd. V puts you in visual line mode, ) jumps to the first non-blank line (skipping the whitespace at the beginning of the line), k moves the cursor up one line. At this point you've selected all the blank lines, so d deletes the selection.
Finally, type O (capital O) followed by escape to crate a new blank line to replace the ones you deleted. Alternatively, replacing dO<Escape> with c<Escape> does the same thing with one less keystroke, so the entire sequence would be ()V)kc<Esc>.
These answers are irrelevant after the updated question:
This may not be the answer you want to hear, but I would make use of ranges. Take a look at the line number for the first empty line (let's say 55 for example) and the second to last empty line (perhaps 67). Then just do :55,67d.
Or, perhaps you only want there to ever be one empty line in your whole file. In that case you can match any occurrence of one or more empty lines and replace them with one empty line.
:%s/\(^$\n\)\+/\r/
This answer works:
If you just want to use normal mode you could search for the last line with something on it. For instance,
/.<Enter>kkVNjd
I didn't test so much, but it should work for your examples. There maybe more elegant solutions.
function! DelWrapLines()
while match(getline('.'),'^\s*$')>=0
exe 'normal kJ'
endwhile
exe 'silent +|+,/./-1d|noh'
exe 'normal k'
endfunction
source it and try :call DelWrapLines()
I know this question has already been resolved, but I just found a great solution in "sed & awk, 2nd Ed." (O'Reilly) that I thought was worth sharing. It does not use vim at all, but instead uses sed. This script will replace all instances of one or more blank lines (assuming there is no whitespace in those lines) with a single blank line. On the command line:
sed '/ˆ$/{
N
/ˆ\n$/D
}' myfile
Keep in mind that sed does not actually edit the file, but instead prints the edited lines to standard output. You can redirect this input to a file:
sed '/ˆ$/{
N
/ˆ\n$/D
}' myfile > tempfile
Be careful though, if you try to write it directly to myfile, it will just delete the entire contents of the file, which is clearly not what you want! After you write the output to tempfile, you can just mv tempfile myfile and tada! All instances of multiple blank lines are replaced by a single blank line.
Even better:
cat -s myfile > temp
mv temp myfile
cat is awesome, yes?
Bestest:
If you want to do it inside vim, you can replace all instances of multiple blank lines with a single blank line by using vim's handy feature of executing shell commands on a range of lines within vim.
:%!cat -s
That's all it takes, and your entire file is reformatted all nice!

How do I join two lines in vi?

I have two lines in a text file like below:
S<Switch_ID>_F<File type>
_ID<ID number>_T<date+time>_O<Original File name>.DAT
I want to append the two lines in vi like below:
S<Switch_ID>_F<File type>_ID<ID number>_T<date+time>_O<Original File name>.DAT
The second line got deleted and the contents of the second line was appended to the first line.
How could I do it using command mode in vi?
Shift+J removes the line change character from the current line, so by pressing "J" at any place in the line you can combine the current line and the next line in the way you want.
Vi or Vim?
Anyway, the following command works for Vim in 'nocompatible' mode. That is, I suppose, almost pure vi.
:join!
If you want to do it from normal command use
gJ
With 'gJ' you join lines as is -- without adding or removing whitespaces:
S<Switch_ID>_F<File type>
_ID<ID number>_T<date+time>_O<Original File name>.DAT
Result:
S<Switch_ID>_F<File type>_ID<ID number>_T<date+time>_O<Original File name>.DAT
With 'J' command you will have:
S<Switch_ID>_F<File type> _ID<ID number>_T<date+time>_O<Original File name>.DAT
Note space between type> and _ID.
This should do it:
J
In vi, J (that's Shift + J) or :join should do what you want, for the most part. Note that they adjust whitespace. In particular, you'll end up with a space between the two joined lines in many cases, and if the second line is indented that indentation will be removed prior to joining.
In Vim you can also use gJ (G, then Shift + J) or :join!. These will join lines without doing any whitespace adjustments.
In Vim, see :help J for more information.
Just replace the "\n" with "".
In vi/Vim for every line in the document:
%s/>\n_/>_/g
If you want to confirm every replacement:
%s/>\n_/>_/gc
If you want to join the selected lines (you are in visual mode), then just press gJ to join your lines with no spaces whatsoever.
This is described in greater detail on the vi/Vim Stack Exchange site.
Press Shift + 4 ("$") on the first line, then Shift + j ("J").
And if you want help, go into vi, and then press F1.
In Vim you can also use gJ.
ََ
Another way of joining two lines without placing cursor to that line is:
:6,6s#\n##
Here 6 is the line number to which another line will be join. To display the line number, use :set nu.
If we are on the cursor where the next line should be joined, then:
:s#\n##
In both cases we don't need g like :s#\n##g, because on one line only one \n exist.

Delete first word of each line

How do I delete first word of each line in Vim?
How about a pattern on each line?
:normal to the rescue:
:%norm dw
It basically replays the arguments as if you were typing them in normal ('non-edit') mode.
From :help :
:norm[al][!] {commands}
Execute Normal mode commands {commands}.
This makes it possible to execute Normal mode commands typed on the
command-line. {commands} is executed like it is typed.
Going for cryptic here, in true vi style:
1Gq10dwjq100000#1
Randy fixed this up in the comments to work on more than 100000 lines:
ggqqdwj#qq#q
For those starting out with Vim, this breaks down to:
gg - Go to first line
qq - Record a macro into register 'q'
dwj#q - The macro:
dw - delete word at cursor
j - go down one line
#q - run the macro in register 'q'
q - Stop recording the macro
#q - Execute the macro in register 'q'
In essence, the macro is recursive - it deletes a word, moves down a line, then calls itself again, repeating for each line until end of file. The final '#q' is the initial (manual) call needed to set the macro off on every line.
I would use something like the following:
:%s/^\w+\s+//
The regular expression will match one or more "word" characters starting at the beginning of the line followed by at least one whitespace character. It will remove the word and any following whitespace. If a line can contain only a single word -- and you still want it removed -- you could use alternation to match either whitespace or the end of line.
:%s/^\w+(\s+|$)//
First word (where word is defined as no whitespace)
:%s/^\s*[^ ]* //g
Delete pattern:
:%s/< insert pattern here >//g
What about this?
:%!cut -s -d' ' -f2-
:%s,^[^ ]*,,
From the beginning of the line match anything, but not a space and replace with none.
Although this is an old question, if someone else is looking to do this you could do use visual block.
press ctrl+v
select all the lines you would want to edit
now use arrow keys to select the entire word
press 'x'
That would delete the first word in all the lines. This method is especially very handy to edit log files

Vim delete blank lines

What command can I run to remove blank lines in Vim?
:g/^$/d
:g will execute a command on lines which match a regex. The regex is 'blank line' and the command is :d (delete)
Found it, it's:
g/^\s*$/d
Source: Power of g at vim wikia
Brief explanation of :g
:[range]g/pattern/cmd
This acts on the specified [range] (default whole file), by executing the Ex command cmd for each line matching pattern (an Ex command is one starting with a colon such as :d for delete). Before executing cmd, "." is set to the current line.
:v/./d
or
:g/^$/d
or
:%!cat -s
The following can be used to remove only multi blank lines (reduce them to a single blank line) and leaving single blank lines intact:
:g/^\_$\n\_^$/d
how to remove all the blanks lines
:%s,\n\n,^M,g
(do this multiple times util all the empty lines went gone)
how to remove all the blanks lines leaving SINGLE empty line
:%s,\n\n\n,^M^M,g
(do this multiple times)
how to remove all the blanks lines leaving TWO empty lines AT MAXIMUM,
:%s,\n\n\n\n,^M^M^M,g
(do this multiple times)
in order to input ^M, I have to control-Q and control-M in windows
How about:
:g/^[ \t]*$/d
This works for me
:%s/^\s*$\n//gc
work with perl in vim:
:%!perl -pi -e s/^\s*$//g
I tried a few of the answers on this page, but a lot of them didn't work for me. Maybe because I'm using Vim on Windows 7 (don't mock, just have pity on me :p)?
Here's the easiest one that I found that works on Vim in Windows 7:
:v/\S/d
Here's a longer answer on the Vim Wikia: http://vim.wikia.com/wiki/Remove_unwanted_empty_lines
Press delete key in insert mode to remove blank lines.
This function only remove two or more blank lines, put the lines below in your vimrc, then use \d to call function
fun! DelBlank()
let _s=#/
let l = line(".")
let c = col(".")
:g/^\n\{2,}/d
let #/=_s
call cursor(l, c)
endfun
map <special> <leader>d :keepjumps call DelBlank()<cr>
:g/^\s*$/d
^ begin of a line
\s* at least 0 spaces and as many as possible (greedy)
$ end of a line
paste
:command -range=% DBL :<line1>,<line2>g/^\s*$/d
in your .vimrc,then restart your vim.
if you use command :5,12DBL
it will delete all blank lines between 5th row and 12th row.
I think my answer is the best answer!
If something has double linespaced your text then this command will remove the double spacing and merge pre-existing repeating blank lines into a single blank line. It uses a temporary delimiter of ^^^ at the start of a line so if this clashes with your content choose something else. Lines containing only whitespace are treated as blank.
%s/^\s*\n\n\+/^^^\r/g | g/^\s*$/d | %s/^^^^.*
This worked for me:
:%s/^[^a-zA-Z0-9]$\n//ig
It basically deletes all the lines that don't have a number or letter. Since all the items in my list had letters, it deleted all the blank lines.

Resources