VI replace a custom number of characters from a custom position - text-editor

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

Related

vi keep only first 10 characters of a column

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.

Replace a line containing certain characters using vi

I'd like to replace all line containining "CreateTime=xxxxx" with "CreateTime=2012-01-04 00:00". May I know how should I do it with vim?
[m18]
Attendees=38230,92242,97553
Duration=2
CreateTime=2012-01-09 22:00
[m20]
Attendees=52000,50521,34025
Duration=2
CreateTime=2012-01-09 00:00
[m22]
Attendees=95892,23689
Duration=2
CreateTime=2012-01-08 17:00
You can use the global substitute operator for this.
:%s/CreateTime=.*$/CreateTime=2012-01-04 00:00/g
You can read the help for the s command from within Vim using:
:help :s
You can read about patterns with :help pattern-overview.
As requested, a bit more about the regular expression match (CreateTime=.*$):
CreateTime= # this part is just a string
. # "." matches any character
* # "*" modifies the "." to mean "0 or more" of any character
$ # "$" means "end of line"
Taken together, it matches CreateTime= followed by any series of characters, consuming the rest of the line.

yank all lines and paste at the end Vim

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.

How do I remove the first string on every line in vim?

I have a text file that's thousands of lines long. Every line starts with a string of 8 hex numbers. I need to remove this string on every line. How do I do this in vim?
Use ^V for block select, highlight your eight columns, and delete as normal.
Or use :s:
:%s/\v^[a-fA-F0-9]{8}//
Replace first 8 hex chars (0-9 digits, a-f/A-F letters) on any line with empty string:
:%s/^[0-9a-fA-F]\{8\}//gc
If the line is
12345678 Something else
a total of 9 chars is to be removed from the head of each line, in VIM
:1,$s/^.........//
should do the trick (9 dots),
: to tell vim you want to enter a command
1,$ means the command affects from line 1 to the last (or g global)
s means substitute
^ means beginning of line
..... means 5 (any) chars
s/^.....// means replace 5 chars at start of line with nothing
edit to match the number of hex chars from the question..
use cut command. This way is much more straight forward.
echo '12345678 Something else' | cut -c 10-
result:
Something else
Just remind, cut index string start from 1 instead of 0.
In vi, we could just run cut in vi:
:%!cut -c 10-

vi, find line and output/output to separate file

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

Resources