vim substitute mulitple characters in a line - vim

Command :%s:a:b will modify line aaa to line baa. The question is how to get result bbb using only one command (not using :%s:a:b 3 times, what I am doing now :-) ).

You need to add g flag at the end, like this:
:%s:a:b:g
When working with regular expressions this flag commonly means a "global" replacement, i.e. replace all occurrences.
The same technique usually works in other tools too that use regular expressions, for example sed, perl, etc.
UPDATE
I am surprised that such a simple answer still keeps receiving upvotes... So for you vim fans out there I recommend this great site where I still keep learning interesting new stuff: http://vimcasts.org/

remember the 'e' flag
:%s:a:b:e
Have a look at this answer Multiple search and replace in one line

Related

vim: Run multiple commands based off of one :global command

Apologies if this has been posted already, for I cannot find an answer, even on the vim wiki.
Is there a way I can run multiple commands in vim command-line mode off of a single :g search?
For example,
:%g/foo/ s/bar/\=#a/g | exe "norm /cat\<enter>\"ayiw"
Which (for what I intend it to do) should, on every line matching foo, replace bar with the contents of register a, and then find the next iteration of cat (even if it is many lines ahead), and put the surrounding word into register a.
Instead, this specific syntax completes the subsitution command using the current contents of the initial a register, and then executes the normal mode command on a single line (after the substitution has been completed).
This example is not my specific use-case but shows one instance where this functionality is useful. I realize I could put it all into a single exe, i.e., %g/foo/exe "norm :s/bar/\\=#a/g\<enter>/cat\<enter>\"ayiw", but I would like to do it the first way, as I feel it is more flexible.
I would prefer to do this using vanilla vim, but if a plugin exists for this, that is an okay alternative. Does anybody know if there is syntax to do such a thing?
Okay a "little bit" dirty, but does this work for you?
:let list = split(execute('g/cat/p'), '\n') | g/foo/ s/bar/\=matchstr(remove(list, 0), '\s\d\+\s\zs.*')/g
It first reads all occurences of cat save them in a list.
Then replace the first bar with the first cat... and so on.
The dirty part ist the matchstr command. the g//p also returns a number for the result so the list looks like this:
1 cat
2 cat
3 cat
...
that's why we have to remove a bit from the front. I would love to hear if someone knows a clean solution for that (I am also interested in a clean vimscript solution, does not have to be a oneliner).
You can do this (at least for multiple :s commands applied to a single :g). Example:
" SHORT STORY TITLES to single word of CapitalizedWords within <h3>s
.,$g/^\L\+$/s/[^A-Z0-9 ]\+//ge|s/\u\+/\L&/ge|s/\<\l\+\>/\u&/ge|s/ \+//ge|s/.*/<h3>&<\/h3>/

Substitute in vim, with special characters

I am trying to use substitute command in vim to enclose all occurences of a particular pattern
\cite{author1}
\cite{author2}
with
(\cite{author1})
(\cite{author2})
Based on other answers in stack exchangeI used the following vim command
%s/\\cite{(\w\+)}/(\\cite{\1})/g
But, no luck. It says "no matches found". I put two back slashes, one of which is supposed to be the escape character. Kindly help.
I know I could use some other editor and finish the job, but I want to know my mistake. Thank you.
please escape ()
%s/\\cite{\(\w\+\)}/(\\cite{\1})/g
You do not need a capture group to get the entire match. You can use \0 or & for the whole match in the replacement portion of your substitution.
:%s/\\cite{\w\+}/(&)/g
If you do want to use a capture group, then you need to escape the capture group/parenthesis.
:%s/\(foo\)/(\1)/g
For more help see:
:h :s%
:h /magic
As mentioned, normally you need escape the parentheses.
You can use very magic mode (\v) to make the regex simpler; removing the need to escape lots of the regex parts, including the parentheses for capturing:
%s/\v(\\cite\{\w+\})/(\1)/g
Knowing what every sign in a regular expression does in vim is sometimes very
difficult, especially for all the modes and configuration variables that this
depends on. For that reason, it is very important to have visual feedback about
what text are we really matching in any moment while crafting regular
expressions.
If you work with neovim, there is a special option called inccommand that you
can enable to live preview the matches and substitution. That way you can figure
out you errors more quickly. This feature is very likely to be included also in
vim in the future, but independently of that, you can also use simple vim to
give you visual feedback if you enable the option incsearch.
With incsearch set, you can watch the matches of / and ? while you write them
just to be sure that the pattern is correct. Later you can exploit a nice
feature from the substitution: if you leave the first section empty, the last
search will be used.
So you could first make the search:
/\\cite{\w\+}/(&)/g
In the meantime, vim will be showing you the matched text visually. Once you
are sure that the pattern is correct press enter, and finally type:
:%s//(\1)<Enter>
Also, in case you want something more powerful than this simple hack, you can go
for my plugin Extend.vim, that can
do that and much more with great visual feedback.

How to edit this file using grep or using cat or using vim or using another tool?

One of my elder brother who is studying in Statistics. Now, he is writing his thesis paper in LaTeX. Almost all contents are written for the paper. And he took 5 number after point(e.g. 5.55534) for each value those are used for his calculation. But, at the last time his instructor said to change those to 3 number after point(e.g. 5.555) which falls my brother in trouble. Finding and correcting those manually is not easy. So, he told me to help.
I believe there is also a easy solution which is know to me. The snapshot of a portion of the thesis looks like-
&se($\hat\beta_1$)&0.35581&0.35573&0.35573\\
&mse($\hat\beta_1$)&.12945&.12947&.12947\\
\addlinespace
&$\hat\beta_2$&0.03329&0.03331&0.03331 \\
&se($\hat\beta_2$)&0.01593&0.01592&0.01591\\
&mse($\hat\beta_2$)&.000265&.000264&.000264 \\
\midrule
{n=100} & $\hat\beta_1$&-.52006&-.52001&-.51946\\
&se($\hat\beta_1$)&.22819&.22814&.22795\\
&mse($\hat\beta_1$)&.05247&.05244&.05234\\
\addlinespace
&$\hat\beta_2$&0.03134&0.03134&0.03133 \\
&se($\hat\beta_2$)&0.00979&0.00979&0.00979\\
&mse($\hat\beta_2$)&.000098&.000098&.000098
I want -
&se($\hat\beta_1$)&0.355&0.355&0.355\\
&mse($\hat\beta_1$)&.129&.129&.129\\
......................................................................
........................................................................
........................................................................
Note: Don't feel boring for the syntax(These are LaTeX syntax).
If anybody has solution or suggestion, please provide. Thank you.
In sed:
$ sed 's/\(\.[0-9]\{3\}\)[0-9]*/\1/g' file
&se($\hat\beta_1$)&0.355&0.355&0.355\\
&mse($\hat\beta_1$)&.129&.129&.129\\
ie. replace period starting numeric strings with at least 3 numbers with the leading period and three first numbers.
Here is the command in vim:
:%s/\.\d\{3}\zs\d\+//g
Explanation:
: entering command-mode
% is the range of all lines of the file
s substitution command
\.\d\{3}\zs\d\+ pattern you would like to change
\. literal point (.)
\d\{3} match 3 consecutive digits
\zs start substitution from here
\d\+ one or more digits
g Replace all occurrences in the line
Concerning grep and cat they have nothing to do with replacing text. These commands are only for searching and printing contents of files.
Instead, what you are looking is substitution there are lots of commands in Linux that can do that mainly sed, perl, awk, ex etc.

Is there a way to elegantly comment specific lines in vim search history, similar to " in command-line history?

I am using vim to edit structured text files.
Sometimes I use search-and-replace feature, and sometimes I am better off with search, followed with a macro, in which case I have several macros at hand, and the choice of one depends upon the particular search result.
In both cases, though I have to spend some effort to arrive at an acceptable regex to satisfy my editing needs. As the regexs are often very long and sophisticated, I end up with both command-line history and search history full of my trial-and-error by-products. The correct regex is not always the last one in a series of attempts, so if I want to reuse the hard-earned regex in a similar editing situation, I have to dig through the pile again.
In search-and-replace scenario I have quickly fixed this with comments that I now put in place at the end of a would-be reusable search-and-replace command string, for example:
:%s/very_long_and_sophisticated_regex/another_long_and_sophisticated_regex/gc "comments on what this search and replace command does and how it might be reused
This way I can easily ignore the piles of stuff in my command line history and quickly find relevant re-use candidates, they are shown in different color. The commands are reusable right away, comments are ignored.
Not so with the search history, though.
Having rtfmed and searched the web, I have not found anything similar. At the moment I put quasi-comments using XXX at the end of reusable search strings, for example:
/search_string_containing_very_long_and_sophisticated_regex XXX comments on what it finds and how it might be re-used
This way I can at least find the right string for re-use, but I have to first delete 'XXX' and the comments.
I wonder if there is a more elegant way of commenting the search strings in search history, similar to command-line history.
You used the word "elegant" in your title, and that I don't have on offer. If instead you can also accept a quirky workaround that relies on Vim internals, here's one.
To restate your problem, it is possible to add comments after Ex :commands,
:AComplicatedExCommand -42 -quux " this fizzes the brobble
:HardToRememberCommand test.txt " use this to brew the framble
but the same is not possible for complicated search /queries (or ?queries).
I've just discovered that you can trick Vim by terminating your search query with a literal null byte:
/[Complicated]*regexp/^# this regexp finds all scrobbles
/another\+Rege\x*p/^# use this to search foo bars
The ^# here is a literal NUL. You can enter it by pressing CtrlV and then 000.
Vim will ignore everything after the null byte, but it'll still show the whole line in the search history, including the "comment".
You can add a regexp branch that never matches, e.g. /\%$indicator\|search string
\%$ is a special Vim atom matching the end of the file. Since that will never match when followed by the indicator text, the first branch (up to \|) will never match and therefore can represent your indicator.
I've created the TaggedSearchPattern plugin to make adding the tag and recalling it even easier.

Vim replacing linefeeds

I resisted Vim, but have now given in. It works large files like a hot knife through butter.
Situation: I have a large text file, I want to put a pipe character at the beginning and ending of each line.
Problem: These Vims and other variations didn't work:
:%s/$/|\$|
:%s/\r/|\r|
:%s/$/|\r|
I suspect it's something simple to fix this, but searching Google and Stack didn't help.
You nearly had it:
:%s/^\|$/|/g
^\|$ means beginning or end of line. In a Vim regex, the | "or" pipe gets escaped. That is followed by /|/g -- replace with | globally.
Personally, I'd prefer the expressiveness of 'surround each line with pipe chars':
:%s/.*/|&|
This, in my brain, is more intuitive than 'replace a non-existing, imaginary character at the start or end of a line'.
It also depends on fewer magic chars (^,$, quoted \| which are all clumsy to type and error prone. (I mean, do you remember to quote the regex |? Do you know the difference between $ and \_$? Did you know some, if not all, of these depend on the 'magic configuration' of vim?)).
The above suffers from none of those.

Resources