Such as title, I want to copy all lines and paste at the end.
BEFORE:
apple
cat
dog
sun
AFTER:
apple apple
cat cat
dog dog
sun sun
Use a substitue command
:%s/.*/& &
Where .* matches everything and & is replaced with the match (in this case the whole line)
Or if you really want to yank the lines you could use a normal command
:%norm yyPJ
Which is run the command yyPJ on every line in normal mode.
Note: These commands will give slightly different output if there is leading whitespace.
If you're on unix-like system:
:%!paste -d' ' % -
Another unix-style answer (though I would go with any of #FDinoff's solution):
:%!awk '{print $1, $1}'
And another :normal answer because there's so many ways to enjoy skinning a cat:
:%norm y$A <C-v><C-r>"
And another one:
:%norm y$Pa<space> <-- just press the <space> bar
Another way , if your text is like this(~ represents blank)
apple
cat~~
dog~~
sun~~
It means that all word has the same numbers of colomn.
you can ctrl-v to select all and move cursor to the end of "apple" and type p to paste.
Related
I am trying to renumber the lines 2,$ in a file using vim a command, I know the command cat -n of nl, I can number the lines, but I didn't get the expected output:
I tried this :2,$s/^\([^,]\)// | 2,$!cat -n
input:
#,Name,Types,Total,HP,Attack,Weaknesses,Strength
493,Arceus,Normal,720,120,120,Fighting,strong
483,Dialga,Steel;Dragon,680,100,120,Fighting;Ground,strong
250,Ho-oh,Fire;Flying,680,106,130,Electric;Water;Rock,strong
.... moer 100 lines
expected output:
#,Name,Types,Total,HP,Attack,Weaknesses,Strength
1,Arceus,Normal,720,120,120,Fighting,strong
2,Dialga,Steel;Dragon,680,100,120,Fighting;Ground,strong
3,Ho-oh,Fire;Flying,680,106,130,Electric;Water;Rock,strong
....
You can use \= to use a sub-replace-expression, and line('.') to get the current line number:
" The parenthesis around `line('.')-1` are not needed, but it seems clearer to me
:2,$s/^/\=(line('.')-1).','/
Edit: just realized you're actually replacing your first column, so you might actually want
:2,$s/^\d\+/\=line('.')-1/
Sorry for the bad english, see this example:
original
a
line01
line02
line03
line04
b
want to become:
a
line01
line01
line02
line02
line03
line03
line04
line04
b
a and b are irrelevant.
I can copy one line and paste, and repeat. Is there any simple solution? like one command?
Using a global command, this could easily be done like this
:g/^/t.
Breakdown
:g start a global command
/^ search for a begin of line (every line matches)
/t. copy the current line
You could also write a vim macro-
With your cursor at line 0, column 0; record a macro, store in register a
qa
Copy the current line; paste it below; move your cursor down to the next line
yypj
Save the Macro
q
Now run the a macro N number of times (it will stop at the bottom of the file regardless)
3#q
For funsies a sed solution:
$ sed 'p' input.txt > output.txt
Using filter, :!, inside of Vim:
:%!sed p
Obligatory awk solution: awk '1;1' input.txt > output.txt.
how do i do this in vi?
awk -F"," awk '{print substr($1,1,10)}'
I only want to keep the first 10 characters of my date column (example 2014-01-01) and not include the timestamp.
I tried to do it in awk but i got this error:
sed: RE error: illegal byte sequence
I believe it is a bash_profile setting error.
This is what i have in my bash_profile:
#export LANG=en_US.UTF-8
#export LOCALE=UTF-8
export LC_CTYPE=C
export LANG=C
in vim, do:
:%norm! 11|D
this will affect all lines in your buffer.
If you like, :s could do this job too.
:%s/.\{,10}\zs.*//
:%s/: apply the substitution to all the lines
.\{,10}: match anything up to 10 times (greedy)
\zs: indicates the beginning of the match
.*: match the rest of the line
/: end of the first part of :s
/: end of the second part of s (since there's nothing between the two /, replace with nothing, ie delete)
For editing blocks of text there is a -- VISUAL BLOCK -- mode accessible via CTRL-V (on Windows ussually CTRL-Q). Then you can press d to delete your selection.
Or with a simple substitute command
:%s/\%>10c.*//
\%>10c - matches after tenth column
. - matches any single character but not an end-of-line
* - matches 0 or more of the preceding atom, as many as possible
Or you can use range
:1,3s/\%>10c.*//
This would substitute for the first three lines.
There is a text file like that
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
mail:x:8:12:mail:/var/spool/mail:/bin/false
ftp:x:14:11:ftp:/srv/ftp:/bin/false
http:x:33:33:http:/srv/http:/bin/false
How to replace in VI all characters in strings 2-4 from 2nd to 5th to 'X'?
UPD:
it's smth like: :2,4s//X/g
I guess I need a regular expression
UPD2: :2,4s/^\(.\)...\|^$/\1XXX/ | 2,4s/^$/ XXX/
Vim only
Try this command:
:2,4s/\%2c.../XXX/
Where:
2,4 is for in strings 2-4
\%2c... is for from 2nd to 5th
XXX is for to 'X'
Both Vim and Vi
As Vi doesn't have \%c, this command should be used instead:
:2,4s/^\(.\).../\1XXX/
Resources
:help :range
:help /ordinary-atom
I'm looking for a command in VI/VIM to search for particular text in the file and grab the whole line and output in either on the screen or separate file. e.g.
This is some line with this _word_ and some other text.
This is some line with this some other text and some other text.
so this would output only the first line..
:redir > output.txt
:g/_word_/p
:redir END
The line will be output to the screen and to output.txt. See :h :redir.
EDIT: I agree with others who suggest using plain old *nix grep if you can. Situations where you might not be able to use grep:
You're searching buffer text that doesn't exist in a file on the filesystem.
You're using Vim-specific regex extensions, like cursor location, column number, marks, etc.
You want do this in a cross-platform way, and grep might not exist on the system you're using.
redir can be useful in these situations.
use the g (global) command:
:g/_word_/y
will yank all lines containing _word_
having mentioned the DOS find command, you probably want to use grep:
grep -h '_word_' * > results
in vi, from command mode
search for _word_
/_word_
yank the line
yy
paste the line
p