I have two lists like these below:
abc.domain.com
defg.domain.com
hijklmn.domain.com
abc.domain.com/sub/
defg.domain.com/anothersub/
hijklmn.domain.com/thirdsub/
I need to make these two lists appear like so:
abc.domain.com?ref=abc
defg.domain.com?ref=defg
hijklmn.domain.com?ref=hijklmn
abc.domain.com/sub/?ref=sub
defg.domain.com/anothersub/?ref=anothersub
hijklmn.domain.com/thirdsub/?ref=thirdsub
How to I accomplish this in vi/vim?
Assume the two lists are in two different buffers. We can do the job using vim's :s command:
For list1:
%s/\v([^.]+).*/&?ref=\1/
For list2:
%s#\v.*/([^/]+)/$#&?ref=\1#
If the two lists are mixed in one buffer, you can use :g command to do the substitution only on a certain target.
Related
let(:aaaaa) { 123 }
let(:bb) { true }
let(:ccc_ccc) { "foo bar" }
I want to copy all variable names (:aaaaa, :bb, :ccc_ccc).
In VsCode, for example, I would use a multi-line selection.
How can I do it in VIM?
Block selection didn't work, once the variable names have a different length.
You could use the command :%norm f:"Qyt) to make your 'q register' contain the
following:
:aaaaa:bb:ccc_ccc
The way it works is as follows:
:%norm means 'to all lines, apply the following normal commands'
f: moves the cursor to the first colon on the line
"Qy appends yanked text to the 'q' register
t) is a motion 'till the next closing parenthesis
This assumes that the 'q' register is already empty (you can use qqq to clear
it). If you only want to do this for a subset of lines, you'd replace the %
with a range (or visual selection).
What you do with the register's contents after that is up to you.
"qp will put them into the buffer, and maybe you'd then do :s/:/\r:/g to
split the lines at the colons like this:
:aaaaa
:bb
:ccc_ccc
If your immediate goal is to have something like this in the default register:
:aaaaa
:bb
:ccc_ccc
then it won't be easy to achieve without the ability to visually select multiple non-contiguous pieces of text of arbitrary length, which Vim doesn't have out of the box.
This means that, if we don't want to use a multiple cursors plugin, we are left with more pedestrian ways involving substitutions, macros, etc.
Assuming the cursor is on the first line, you could do something like:
:,+2t+2 " copy the block below itself
:'[,s/.*(\(.*\)).*/\1 " remove everything you don't need
:'[,d " cut the three lines to the unnamed register
But Vim works best when it is used with intent. "Copy this" is rarely a goal in and of itself: it generally is one of the several low-level steps necessary to complete a higher-level task (which itself might be one of the steps of another even higher-level task). What one intends to do with the copied text often plays an important role in choosing the best strategy. Here, your actual goal may have been to get the three variable names on three lines right below their definition, something that actually doesn't imply copying them, so the two first steps would have been enough.
This question already has answers here:
How can I replace a pattern only on lines that do or do not contain another pattern?
(2 answers)
Closed 1 year ago.
Is there a way to specifically search for a pattern first and then replace using %s
Why I specifically chose vim is because I can easily make change using :wq
Consider I got a file abc.txt where I need to replace all two's with three:
cat abc.txt
one two
two two
one two
But I only need to replace only those lines that is having "one".
Is there a way to first grep or filter lines having "one" inside vim and then replace using
:%s/two/three/g.
I need a one-liner command that can filter out all lines having "one" and perform substitution.
Sample output
cat abc.txt
one three
two two
one three
Many thanks in advance!
Use a Capture Group or a Look Behind Pattern to Solve Substitution
This ex command should meet your needs:
:`%s/\(one\) two/\1 three/
This is also a classic look behind pattern matching problem (:help /#<=).
:%s/\(one\)\#<= two/ three/
Another approach might be to use \zs, \ze pattern matching technique. Look up :help \zs.
%s/one \zstwo\ze/three/
I am trying to get vim to set my paragraph on a single line. Say I have this text :
this is a sentence
this is another sentence
and another
how can I get the following:
this is a sentence this is another sentence and another
Thanks
Per line? Have a look at the J operator (:h J).
for multiple lines? [COUNT]J will do it (3J in your example)
Per block? something like v}J should do it. Works of course with every visual selection.
Per regex? Use the :g command f.e. :g/this/norm J
You should specify exactly what you want. since there are as always in vim a lot of different solutions.
With spaces between the joined lines
:%join
Without space add "!"
:%join!
Using join your cursor will not move
I want to perform a number of substitutions of the following kind across several files:
"\includegraphics{all.png}" → "\includegraphics[width=\linewidth]{all.png}"
I would like to do that without Sed, using only Vim. However, when I do it, I always replace the buffer by accident with something like space so wasting a lot of keys. How can I do it fast?
Smallest amount of keys wins!
Start inside Vim: getting the matches to buffers
:grep -r "includegraphics" Sections/*
A flexible way of performing some actions in a group of files using
Vim is to collect the list of their names into the argument list (see
:help arglist), and then iterate through it executing the desired
command.
In order to do the first step, use commands :args, :argadd, and
:argdelete. For instance, to set the argument list to the names of
all files that have the .tex extension in the current directory and
its subdirectories, run:
:args ./**/*.tex
To perform the second step, use the :argdo command:
:argdo %s/\\includegraphics\zs\ze{all.png}/[width=\\linewidth]/g
Replace in all buffers
:bufdo %s/\\includegraphics\{all\.png\}/\includegraphics[width=\linewidth]{all.png}/ge
This question was helpful for getting a count of a certain pattern in Vim, but it would be useful to me to store the count and sum the results so I can echo a concise summary.
I'm teaching a class on basic HTML to some high schoolers, and I'm using this script to be quickly check numbers of required elements throughout all their pages without leaving Vim. It works fine, but when students have more than 10 .html files it gets cumbersome to add up the various sections by hand.
Something like:
img_sum = :bufdo %s/<img>//gen
would be nice. I think I'll write a ruby script to check the pages more thoroughly and check for structure, but for now I'm curious about how to do this in Vim.
The problem can be solved by a counter separate from the one built-in into the
:substitute command: Use Vim-script variable to hold the number of pattern
matches. A convenient way to register every match and modify a particular
variable accordingly, is to take advantage of the substitute with an
expression feature of the :substitute command (see :help sub-replace-\=).
The idea is to use a substitution that evaluates an expression increasing
a counter on every occurrence, and does not change the text it is operating
on.
The first part of the technique cannot be implemented straightforwardly
because it is forbidden to use Ex commands in expressions (including \=
substitute expressions), and therefore it is not possible to use the :let
command to modify a variable. Answering the question "gVim find/replace
with counter", I have proposed a simple trick to overcome that limitation,
which is based on using a single-item list (or dictionary containing a single
key-value pair). Since the map() function transforms a list or a dictionary
in place, that only item could be changed in a constrained expression context.
To do that, one should call the map() function passing an expression
evaluating to the new value along with the list containing the current value.
The second half of the technique is how to avoid changing text when using
a substitution command. In order to achieve that, one can make the pattern
have zero-width by prepending \ze or by appending \zs atoms to it (see
:help /\zs, :help /\ze). In such a way, the modified pattern captures
a string of zero width just before or after the occurrence of the initial
pattern. So, if the replacement text is also empty, substitution does not
cause any change in the contents of a buffer. To make the substitute
expression evaluate to an empty string, one can just extract an empty
substring or sublist from the resulting value of that expression.
The two ideas are put into action in the following command.
:let n=[0] | bufdo %s/pattern\zs/\=map(n,'v:val+1')[1:]/ge
I think that answer above is hard to understand and more pretty way to use external command grep like this:
:let found=0
:bufdo let found=found+(system('grep "<p>" '.expand('%:p') . '| wc -l'))
:echo found