I need to make next task:
file:
string1 data1 data
I need to create more strings with only changes in digits
string2 data2 data
string3 data3 data
string4 data4 data
How can i do it fast ?
select that input line, yank it into buffer a: "ayy.
Then record the following sequence: qq
"ap Paste the line below
ctrl-a Increment the digit
w Move forward one word
ctrl-a Increment the digit
"ayy Yank this line in as your new baseline
End your macro with q
Then repeat it as many times as you need (let's say 42), with 42#q
Several plugins manage that: visincr.vim, increment.vim.
I use visincr and that is very easy: Visual block, :I.
Related
Suppose I have something like this:
line 1 with text
line 2 with text
line 3 with text
line 4 with text
I want to unindent all of these lines to the beginning, like this:
line 1 with text
line 2 with text
line 3 with text
line 4 with text
Shift + V < gives me ONE level of un-indentation. How can I get them all to the beginning? Sorry, I'm having trouble phrasing this...
There are two different ways you could do this:
Visually select all of the lines, press <, and then press . as many times as you need until there is no indent left. Or if there are a specific number of lines you would like this on, you could do something like
5<< (unindent 5 lines)
<j (unindent this line and the next)
<ip (unindent inside this paragraph)
followed by as many . as you need.
Select all of the lines, and then type either :norm d^ or :s/^\s*
Also, Shift-V + V + < is basically the same as <<.
I want to convert the vertical text in my file to horizontal. like
1
2
3
to
1 2 3
I can do this using the tr command tr '\n' ' ' <file
but I want to do this using vim
An easy one. Use a range from first line until last one and join them with an space between them:
:0,$join
Select the lines and join them with J.
From :h J :
*J*
J Join [count] lines, with a minimum of two lines.
Remove the indent and insert up to two spaces (see
below).
*v_J*
{Visual}J Join the highlighted lines, with a minimum of two
lines. Remove the indent and insert up to two spaces
(see below). {not in Vi}
And, just for the fun of it:
:{fromLine},{toLine}!tr '\n' ' '
Another way:
By replacing \n with
:{fromLine},{toLine}s/\n/ /g
Let's say I'd like to write a 5x5 text block, such as
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
And I want to do it using nested iteration.
In pseudocode it would look like
do five times ((do five times (type 'a')) change line)
So my first guess was to simply convert that as
5 ((5 (i a esc)) enter)
But I can't do that, because Vim doesn't support use of parentheses for specifying execution order. And simply typing
5 5 i a esc enter
will of course not work, since that will just produce a single line with 55 'a's and a newline.
So my question is: Is there a way to write text blocks using nested iteration in Vim? I know that there are other ways to write text blocks, but I want to know if this is possible, just out of curiosity.
You cannot do this directly, you need to use a register, expression, or macro:
qq5aa<Esc>a<CR><Esc>q4#q
qq - record macro
5aa<Esc> - insert 5 a's
a<CR><Esc> - insert line break
q4#q - stop recording, repeat 4 more times
I do not normally like one-liners, but this seems to work:
:for i in range(5) | for j in range(5) | execute 'normal ia' | endfor | execute "normal A\<CR>" | endfor
and this is a lot shorter:
:for i in range(5) | execute 'normal 5aa' | put='' | endfor
<esc> i a <esc> x 5p dd 5P
esc - switch to normal mode
i - switch to insert mode
a - print "a"
esc - switch to normal mode
x - deleta "a"
5p - paste a 5 times ("aaaaa")
dd - delete line "aaaaa"
5P - paste line "aaaaa" 5 times
:norm 5oaaaaa
is the simplest way I could think of to obtain a 5x5 matrix of a's but I don't think it satisfies your curiosity.
One could also do:
:norm Oaaaaa
5#:
but that's not really recursive either.
So… I don't know!
In vim, how can I paste multiple lines of code after every line of a visual block?
What I have is:
foo
bar
1
2
3
What I am trying to do is:
1
foo
bar
2
foo
bar
3
foo
bar
Is there a way to easily accomplish this?
You can cut it to the default register and do a global replacement for the rest of lines, like this:
Go to first column of first line of the file:
gg0
Cut data:
3dd
Do a global repeat for every line of the file and paste it:
:g/^/put
It yields:
1
foo
bar
2
foo
bar
3
foo
bar
assume that you want to copy and paste line number 1 2 3, run this command:
:g/^\S/1,3t.
then the text foo bar would be copied to right place. then you can remove the two lines.
You can also change the 1,3 to other range.
Not fully automated but almost there:
Visually highlight desired rows to copy with Shift+V
Delete with d
Move to first line ("1") and start recording with q followed by some letter, i.e., a.
Paste with p and then move down to the next line ("2"). Stop recording with q.
Now just repeat the last recorded command with ##, or + the designated letter, i.e., #a.
Suppose I have the following text.
a test1
b test2
a test3
b test4
what is the command to use to extract out the lines that start with the letter a and put them in the end of the file like this?
b test2
b test4
a test1
a test3
when I used :g/^a/d and p, the only last match is pasted:
b test2
b test4
a test3
You're only seeing a test3 at the end, because :d sets (not appends) the default register. Since :g executes the given command once per line that matches the pattern, only the last line is in the default register when you paste.
The canonical way to do this would be to use the :move (abbreviated as :m) command -- :g/^a/m $. For every line that matches ^a, move it just past the last line ($).
A slight modification to your initial approach would be to have :d append to a register, and then paste that register afterward.
:let #a='' " Clear register a
:g/^a/d A " For every line that matches ^a, delete it
" and append the contents to register a
:$put a " Paste the contents of register a after the last line
The last part could also be done using the normal mode command "ap.