I see how to search and replace in specific lines, specifying by line number, and how to search and replace using the current line as reference to a number of lines down.
How do I search and replace in the current line only? I'm looking for a simple solution that does not involve specifying line numbers as the linked solutions do.
Replace all occurrences of str1 with str2 in certain line:
:s/str1/str2/g
remove the g option if you want to replace only the first occurrence.
You can use . for the current line, like:
:.s/old/new/
This will change old by new in the current line only.
If you want to search and replace all of the matched word in the current line, you could easily use simple substitute (s) with g modifier in command mode.
:s/search/replace/g
If you just want to search and replace the first matched word in the current line, just move away the g modifier from your command.
:s/search/replace/
Ref: :help substitute
Confirm (c) and Replace :
:s/foo/bar/gc
Find the occurrence of 'foo', and before replacing it with 'bar' ask for confirmation.
Vim gives you these options :
replace with bar (y/n/a/q/l/^E/^Y)?
y - yes
n - no
a - replace all occurrences
q - quit
l - replace the current and stop (last)
^E (CTRL + e) - scroll down
^Y (CTRL + y) - scroll up
Now, in your case you can use the combination of y, n and l to achieve your purpose.
Related
I have a text file in which many lines contain twice the symbol =, as in:
Animals:
clown=fish=vertebrate
cow=mammal=vertebrate
bug=insect=invertebrate
slug==snail
etc
I want to delete everything that is after the second = on each line only if the two = are not together, resulting in:
Animals:
clown=fish
cow=mammal
bug=insect
slug==snail
etc
How I can I do this?
I guess search for the second occurence of =, then select all results, then select until the end of line, then delete, but most of these steps I couldn't find a easy way to do.
This should be enough:
%s/=[^=]\+\zs=.*//
The interesting part is \zs. Look for it in the docs via :help \zs.
Beside that, I'm matching an equal sign (the first =) followed by 1 or more (\+) characters other than the equal sign ([^=]), followed by another equal sign.
Press : to go to command mode, then run this:
%s/\(\w\+=\w\+\).*/\1/g
Explanation: in entire file (%) substitute line with result from \w\+=\w\+ search pattern (one equals sign, surrounded by non-zero-length words-characters.
Since this will only match on lines where the first = is surrounded by word-characters, it won't apply to lines like slug==snail
One option is to use :normal
:%norm f=lf=D
This uses f to find the = character move to left, then search for another = using f before deleting with D. If an error occurs then that line is skipped
I known there are fx and Fx to move the cursor to the next/previous x occurrence in one line.but this command is in one line.
now I want to move cursor to the next line which first character is x,
is there any command the vim supply can achive this?
Try using search command by typing /^\s*x in normal mode
/ starts forward search
^ stands for the start of a line
\s* stands for none or some white space
x stands for x, the character you want to search
You may want read some vim help manuals first;
For example:
:help /
:help usr_27
:help pattern
To find a character in next/previous line
You can use j0fx to search the first occurrence of x in next line.
You can use k0fx to search the first occurrence of x in previous line.
Explanation:
j - down arrow / move one line down
k - up arrow / move one line up
0 - move to first character in the current line
fx - find the first occurrence of x in current line.
To find the character's next/previous occurence in any line
/x
where x is the character
Then press n to go to next occurrence of it. Press N to go to previous occurrence of it.
I have a list of products to place on a rails seed and I would like to instead of put brackets one by one on the list with a command place the brackets on the whole list?
for example:
1. Dakine
2. Dale of Norway
3. Dan Post
1. ["Dakine"],
2. ["Dale of Norway"],
3. ["Dan Post"],
I searched on the help but did not find any about. Thanks.
You can record a macro in Vim and repeat that.
If you are on number 1, you can do following:
qqf a["Esc$a"],Esc0jq
Explanation:
qq: Start recording macro in register q
f: Go to first space character
a: : Insert after (the space character from above)
\[": Insert those characters
Esc: Back to normal mode
$: Go to end of line
a: Insert after (end of line)
"],: Insert the characters
Esc: Back to normal mode
0: Jump to start of line
j: Go down one line
If you have 100 such lines, you can do 100#q to achieve your result.
With vim substitute command:
:%s/.*/["&"]/
If you don't want to operate on all lines, then select the ones you want to transform or note the related line numbers, and then type :s/..... without the %. You'll see actually :'<,'>s this range represent the visually selected lines, and vim adds it automatically in visual mode.
On Atom you can enable the find to use Regex in the search(there is a button next to the search field)
Then you can search for something like (^.*$) to get every line separated by groups and in the Replace field you use ["$1"],. The $1 represents the value matched by the Regex.
Then just do a Replace All and remove the last comma in your list if needed.
I know in VIM how to search a string and delete the text till the start/end of line but I would like to know if it is also possible to delete all text in line before or after highlighted search pattern.
If you want to do this across all lines and don't want to retype your search term I'd suggest the following:
:%s/.*\ze<Ctrl-r>///
What this does is:
%s/: substitute across all lines in a file
.*: match any character
\ze: end matching so the rest of the pattern is not substituted
<Ctrl-r>/: insert text from the '/' register (which is the search register)
//: replace with nothing
Edit: Forgot about the after part. My suggestion to remove both at the same time would be:
:%s/.*<Ctrl-r>/.*/<Ctrl-r>//
To delete the text before FOO on the same line:
:s/^.*\(FOO\)/\1/
From beginning of line to the beginning of highlighted search pattern: 0dn
From after end of highlighted search pattern to the end of line: $N//e<Enter>lD
These will work in most of the cases.
I can't comment on other answers, so I answer here, but I am referring to the answer from xofon:
Just add a '%' in the command line, which would make do for all lines in a file.
delete all chars after ']' in all lines
:%s/\(\]\).*$/\1/
delete all chars before ' -- ' in all lines in a file
:%s/^\( -- \).*/\1/
To delete all text in the line line both before and after the search match you could also do:
:g//norm gnd0PlD
This executes normal mode commands on all lines that match the last search pattern. The commands are gn to select the match, d to delete it, 0P to paste it at the beginning of the line, l to move to the left (after the text that was just pasted) and D to delete until the end of the line. I'm given to understand gn is a fairly recent addition to vim, so YMMV.
say I have this line
= function (x, y, word);
and I want to convert it to
word = function (x,y);
Thus far, I have been manually selecting the word, then 'x', and then paste it at the beginning. And then I would remove unnecessary comma.
Is there a more efficient way to accomplish the same thing?
Don't create weired functions or macros, as many advanced users may suggest you, but learn simple commands, which can help you when you would need to make similar, but slightly different substitution.
My solution would be: place cursor on the comma, and type: xxdw^Pa <C-[>
Description:
xx - delete comma and space
dw - delete word
^ - place cursor on the beginning of text in line
P - place deleted text before cursor
a - add space after word
<C-[> - escape to return to normal mode, you can also press <ESC> if you like, or don't press at all
And how to place cursor in comma? Learn about f,, F,, t,, T,, w, b and e to move faster around your text.
:%s/\(.*\),\([^)]*\)/\2\1/
EDIT:removed /g
EDIT2: the %s is only if you want to do this for the entire file. if you just want to do this for the current line then replace % with . (a dot)
I'd suggest recording a macro: (starting at the beginning of the line)
qq2f,2xdw0Pa <esc>0jq, then running that macro wherever you need it: #q.
Try this: :dw to cut the current word, move to beginning of line, then :p to paste the buffer there.
Or you could use a regular expression.
:s/\(^.*\), \(\a\+\)\();\)/\2\1\3/
(Match up to the last comma) -> \1
(match last argument) -> \2
(Match closing brace and semicolon) -> \3
The reorder the matched terms as you need.
Place cursor over word and type:
"0diw delete word and store it in register 0
dF, delete backwards up to and including ,
^ place cursor at first character in line
"0P paste word
I would suggest to map this to a key.