vim search and replace successive string occurrence with different string - linux

Let’s say I have multiple STRING occurrences. I want to replace the 1st occurrence with STRING_A, 2nd occurrence with STRING_B, 3rd occurrence with STRING_C.
e.g
Color of my pant is STRING. Color of my hair is STRING. Color of my car is STRING.
After I run search and replace, I should get:
Color of my pant is STRING_A. Color of my hair is STRING_B. Color of my car is STRING_C.
Any help will be greatly appreciated.

From vim wiki:
let #a=1 | %s/STRING/\='STRING_'.(#a+setreg('a',#a+1))/g
But this will give you STRING_1, STRING_2 etc.
Slight modification gives the desired result:
let #a=65 | %s/STRING/\='STRING_'.nr2char(#a+setreg('a',#a+1))/g
If you want to get the substitutions from an array, first define an array:
:let foo=['bar','baz','bak']
Then do the substitution:
let #a=0 | %s/STRING/\=get(foo, #a+setreg('a',#a+1))/g
This will give you:
Color of my pant is bar. Color of my hair is baz. Color of my car is bak.

You can define a List of replacements, and then use :help sub-replace-expression to pop replacements off it:
:let r = ['bar', 'baz', 'bak']
:%substitute/STRING/\=remove(r, 0)/g

Related

How to recode strings in Stata?

I would like to change the values in my Nationality variable. For some countries, there is a space after the name of the country ("Germany" and "Germany "), so that they don't appear to be the same country when looking at frequencies. I tried using "encode" to make the values numeric, so that I could use "recode" to change the values, but that gave me the error "unknown el Germany in rule". I attached a screenshot.
Screenshot of data
recode is for numeric variables only, you can use replace.
replace Nationality = "Belgium" if Nationality == "Belgium "
However, a more convenient way for the problem at hand is strtrim(), which removes leading and trailing spaces.
replace Nationality = strtrim(Nationality)

How to subtract from numbers following a string in VIM?

I am trying to subtract from numbers following a string in VIM, for example this (searched) input:
CustomModelData: 1
And my preferred (replaced) output:
CustomModelData: -2147483647
The number that I am trying to subtract from the numbers is 2147483648. I tried using this in VIM, but it doesn't work since there is a string in the expression, I want to keep the string while also subtracting from the number that follows:
:%s/CustomModelData: \d\+/\=/CustomModelData: submatch(0)-2147483648/g
You can use following minor adjustment to have the match start at the number so the replacement only sees the number to adjust
%s/\vCustomModelData: \zs\d+/\=submatch(0)-2147483648/g
\zs anything, sets start of match
If each number is on a separate line of the file, then you can match relevant lines and use the Ctrl+X subtraction operator on them:
:g/CustomModelData:/ norm 2147483648^X
(For the ^X, type Ctrl+X.)

Extracting first two words from excel before colon

I want to extract the first two words in the following cell C2 before the colon
John Smith: Not attending today
=TRIM(LEFT(C2, FIND("~",SUBSTITUTE(C2, " ", "~ ",2)&"~")))
I tried the above formula but it gives me "John Smith:" it gives me the colon as well
How can I just get John Smith
How about:
=LEFT(C2,FIND(":",C2)-1)
As you probably know, the FIND will tell you what position the colon is at. From there, it seems like a good place to use the "LEFT" function to count X number of characters before that position (the -1 is what makes it stop at the character before the colon)
Note that this only looks for the first colon, and also that if there's no colon, you'll get a "#VALUE" error, so if that's a possibility you're concerned about, you would need to handle it.
Alternate,
=REPLACE(C2, FIND(":", C2), LEN(C2), "")
' or the reverse as,
=REPLACE(C2, 1, FIND(":", C2)+1, "")

How do I replace a text string with a number, based on a key word contained in the cell

I have a string variable with short text strings. I want to replace all the text strings with numbers based on key words contained inside the individual cells.
Example: Some cells states "I like cats", while others "I dont like the smell of wet dog".
I want to assign the value 1 to all cells containing the word cat, and the number 2 to all cells containing the word dog.
How do I do this?
This will put 1 in NewVar when "cat" appears in OldVar, 2 for "dog", 3 for "mouse":
do repeat wrd="cat" "dog" "mouse"/val= 1 2 3.
if index(OldVar, wrd)>0 NewVar=val.
end repeat.
This is only good if there will never be a cat AND a dog in the same sentence. If you do have such cases you should go this way:
do repeat wrd="cat" "dog" "mouse"/NewVar=cat dog mouse.
compute NewVar=char.index(OldVar, wrd)>0.
end repeat.
This will create a new variable for each of the possible words, putting 1 in cases where the word appears in OldVar, 0 when it doesn't.
Apparently you have to open a syntax window and enter this command:
COMPUTE newvar=CHAR.INDEX(UPCASE(VAR1),"ABCD")>0
newvar is the name of the new variable.
VAR1 is the name of the variable to be searched.
ABCD is the text to be searched for. NOTE: This must be in CAPITAL letters.
newvar will recieve a value of 1 if the text is found.

Align at longest word

I have the following code:
a = 123
p.value 0.123
p.long.name = "abc"
How can I align each line like shown below in vim?
a = 123
p.value = 0.123
p.long.name = "abc"
Thanks for any hints.
Without plugin:
:%s/=/ &/
:%s/\%13c\s\+=/=
First command will insert spaces before first equal signs on all lines, second one will remove all spaces before an equal sign at 13th column. You could also use Visual block selection and <..... to shift left as many times as necessary.
However this is really unclean. With the tabular plugin you just type :Tab /=/ and this will do the work and the range will be calculated automatically (greatest range around the cursor in which all lines match the pattern).

Resources