VI switch and replace with vi. - vim

This is a config file, and a swith failed, so the networking
guy wanted to set up a new path to the swith, and I needed to change the ports - FAST.
So what i used was %s/:64*$/:57000/g and that did not change them.
I ended up doing them by hand. How could I quickly have changed the :
in vi?
Addr.corp-unix-b1 = corp6503xap:64001
Addr.corp-unix-b2 = corp6503xap:64002
Addr.corp-unix-b3 = corp6503xap:64003
Addr.corp-unix-b4 = corp6503xap:64004
Addr.corp-unix-b4-dia = corp6503xap:64005
Addr.corp-unix-b5 = corp6503xap:64006
Addr.corp-unix-b6 = corp6504xap:64007
Addr.corp-unix-b6-aapl = corp6504xap:64008
Addr.corp-unix-b7 = corp6504xap:64009
Addr.corp-unix-b8 = corp6504xap:64010
Addr.corp-unix-b8-spy = corp6504xap:64011
Addr.corp-unix-b8-fas = corp6504xap:64012
Addr.corp-unix-b8-2 = corp6504xap:64013
Addr.corp-unix-8a-gld = corp6504xap:64014
Addr.corp-unix-b9 = corp6504xap:64015
Addr.corp-unix-b10 = corp6504xap:64016
Addr.togen-xpho-b6-aapl = corp9189pap:3333

Your expression is missing a ., so you were trying to match 6 followed by a variable number of 4's. If you have the ., then you are matching the expression 64 followed by a variable number of any character to the end of line.
%s/:64.*$/:57000/g

In regular expressions, * indicates 0 or more of the preceding character, which in your case is 4.
. matches any character, so your substitution would be written :%s/:64.*$/:57000/g

Just to provide an alternate solution in the spirit of SE:
You could use :g in combination with :normal
:g/:64/norm $bC57000
This finds lines with :64, goes to the end of the line, moves the cursor to the beginning of the word and changes the remaining of the line to 57000.

Related

How to replace a `\norm{ some string }` by `\| some string\|` quickly? [duplicate]

This question already has answers here:
Find and replace strings in vim on multiple lines
(11 answers)
Vim - Capture strings on Search and use on Replace
(4 answers)
Closed 3 years ago.
I am editing a markdown file with vim. This file exist many string \norm{ some string }. I want to replace them by \| some string \|. Does there exist any quick way? Thanks very much.
The answer in Find and replace strings in vim on multiple lines can not answer my question. It just talk about general replacing for one line and multi line. Here I want to replace a surrounding and keep the string in the surrounding.
What you're looking for are so-called capture groups and backreferences. Provided there are no nested forms (curly braces inside do not mean a problem in themselves) and forms spanning multiple lines, a quick solution could be: %s/\\norm {\(.*\)}/\\|\1\\|/g.
The \1 in the substitution part refers to the group captured by \(.*\), i.e. the original content inside the outermost pair of curly braces. See e.g. http://www.vimregex.com/#backreferences for more.
You could also use a macro to accomplish what you want.
Place your cursor on the first line that have the pattern you want to substitute. Then start recording the macro:
qq0ldwr|$xi\|ESCjq
Meaning:
qq = start recording a macro (q) in register q
0 = move to the beginning of the line
l = move one char to the right
dw = delete the word
r| = substitute what is under the cursor with a "|"
$ = move to the end of line
x = delete last char of the line
i = insert mode
\| = insert chars "\|"
ESC = exit insert mode
j = move to next line
q = stop recording
Execute the macro with:
#q
Execute the macro once again:
##
Keep doing it for as many lines as needed, or use:
<number>##
ex. 100##
To execute the macro number times.

Groovy replace everything after character

I need to replace all content after a specific character in groovy with the value of a parameter,
my string is :
env.APP_VERSION="1.9"
And I would like to replace everything after the = sign with the value of a certain parameter let's call it $PARAM.
I was able to trim everything after the = sign,
but not replace it...
result = result.substring(0, result.indexOf('APP_VERSION='));
any help would be appreciated.
One of possible solutions is, indeed, to use regex. It should include:
(?<==) - A positive lookbehind for =.
.* - Match all chars (up to the end).
So the script can look like below:
src = 'env.APP_VERSION="1.9"'
PARAM = '"xyz"'
res = src.replaceFirst(/(?<==).*/, PARAM)
Another solution is to split the string on = and "mount" the result string
from:
The first string from split result.
= char.
Your replacement string.
This time the processing part of the script should be:
spl = src.split('=')
res = spl[0] + '=' + PARAM
Without knowing about your original intentions you have 2 options:
1) Do not reinvent the wheel and use GString magic:
String ver = '1.9'
String result = "env.APP_VERSION=\"$ver\""
2) use some regex:
result = result.replaceFirst( /APP_VERSION="[^"]+"/, 'APP_VERSION="something"' )

How do I remove lines from a string begins with specific string in Lua?

How do I remove lines from a string begins with another string in Lua ? For instance i want to remove all line from string result begins with the word <Table. This is the code I've written so far:
for line in result:gmatch"<Table [^\n]*" do line = "" end
string.gmtach is used to get all occurrences of a pattern. For replacing certain pattern, you need to use string.gsub.
Another problem is your pattern <Table [^\n]* will match all line containing the word <Table, not just begins with it.
Lua pattern doesn't support beginning of line anchor, this almost works:
local str = result:gsub("\n<Table [^\n]*", "")
except that it will miss on the first line. My solution is using a second run to test the first line:
local str1 = result:gsub("\n<Table [^\n]*", "")
local str2 = str1:gsub("^<Table [^\n]*\n", "")
The LPEG library is perfect
for this kind of task.
Just write a function to create custom line strippers:
local mk_striplines
do
local lpeg = require "lpeg"
local P = lpeg.P
local Cs = lpeg.Cs
local lpegmatch = lpeg.match
local eol = P"\n\r" + P"\r\n" + P"\n" + P"\t"
local eof = P(-1)
local linerest = (1 - eol)^1 * (eol + eof) + eol
mk_striplines = function (pat)
pat = P (pat)
local matchline = pat * linerest
local striplines = Cs (((matchline / "") + linerest)^1)
return function (str)
return lpegmatch (striplines, str)
end
end
end
Note that the argument to mk_striplines() may be a string or a
pattern.
Thus the result is very flexible:
mk_striplines (P"<Table" + P"</Table>") would create a stripper
that drops lines with two different patterns.
mk_striplines (P"x" * P"y"^0) drops each line starting with an
x followed by any number of y’s -- you get the idea.
Usage example:
local linestripper = mk_striplines "foo"
local test = [[
foo lorem ipsum
bar baz
buzz
foo bar
xyzzy
]]
print (linestripper (test))
The other answers provide good solutions to actually stripping lines from a string, but don't address why your code is failing to do that.
Reformatting for clarity, you wrote:
for line in result:gmatch"<Table [^\n]*" do
line = ""
end
The first part is a reasonable way to iterate over result and extract all spans of text that begin with <Table and continue up to but not including the next newline character. The iterator returned by gmatch returns a copy of the matching text on each call, and the local variable line holds that copy for the body of the for loop.
Since the matching text is copied to line, changes made to line are not and cannot modifying the actual text stored in result.
This is due to a more fundamental property of Lua strings. All strings in Lua are immutable. Once stored, they cannot be changed. Variables holding strings are actually holding a pointer into the internal table of reference counted immutable strings, which permits only two operations: internalization of a new string, and deletion of an internalized string with no remaining references.
So any approach to editing the content of the string stored in result is going to require the creation of an entirely new string. Where string.gmatch provides an iteration over the content but cannot allow it to be changed, string.gsub provides for creation of a new string where all text matching a pattern has been replaced by something new. But even string.gsub is not changing the immutable source text; it is creating a new immutable string that is a copy of the old with substitutions made.
Using gsub could be as simple as this:
result = result:gsub("<Table [^\n]*", "")
but that will disclose other defects in the pattern itself. First, and most obviously, nothing requires that the pattern match at only the beginning of the line. Second, the pattern does not include the newline, so it will leave the line present but empty.
All of that can be refined by careful and clever use of the pattern library. But it doesn't change the fact that you are starting with XML text and are not handling it with XML aware tools. In that case, any approach based on pattern matching or even regular expressions is likely to end in tears.
result = result:gsub('%f[^\n%z]<Table [^\n]*', '')
The start of this pattern, '%f[^\n%z], is a frontier pattern which will match any transition from either a newline or zero character to another character, and for frontier patterns the pre-first character counts as a zero character. In other words, using that prefix allows the rest of the pattern to match at either the first line or any other start-of-line.
Reference: the Lua 5.3 manual, section 6.4.1 on string patterns

Vim - Navigate to next differing indent

Is there a way in Vim in which I could navigate to the next differing indent level?
So from here to there for example:
-> var a = 1;
var b = 2;
var func = function(){
-> return a + b;
}
This should work for indents made up of spaces (not tabs):
call search('^ \{0,'.eval(indent(".")-1).'}\S\|^ \{'.eval(indent(".")+1).',}\S')
This is made up of two regular expressions:
^ \{0,'.eval(indent(".")-1).'}\S matches a smaller indent, using the \{n,m} construction matching from n to m of the preceding space.
^ \{'.eval(indent(".")+1).',}\S' matches a larger indent, using the \{n,} construction matching at least n of the preceding space.
The regexes are sandwiched between ^ and \S to apply only to the leading whitespace on the line. Then they are joined by the \| ('OR') operator.
Of course the search() call could be mapped to a key combination for convenience.
EDIT
Chris Johnsen points out that the calls to eval() are superfluous, so the command can be reduced to this:
call search('^ \{0,'.(indent(".")-1).'}\S\|^ \{'.(indent(".")+1).',}\S')

VIM: How to avoid substitution within substitution?

I created a function to search a custom number of empty lines (with or without spaces) and to replace them with a new (custom) number of empty lines.
fun! s:AddRemoveNumbEmptyLines()
if !exists("emptylinesbefore")
let emptylinesbefore = "How many empty lines do you search? \n (p.e. 2,3 4, ,3)"
endif
let b = inputdialog(emptylinesbefore)
if !exists("emptylinesafter")
let emptylinesafter = "How many empty lines must it be?"
endif
let c = inputdialog(emptylinesafter)
let m = repeat('\r', c)
exe 's/\(^\s*$\n\)\{'.b.'}/'.m.'/gc'
endfun
Let say b = 2, (2 and more) AND m = 3
If vim finds 4 empty lines it does a substitution to 3 empty lines.
(thats ok).
But when I refuse the substitution request (I use the "c" (confirm) flag) it finds at the same place 3 empty lines and asks again if it has to be replaced with 3 empty lines. When I refuse again, it finds at the same place, 2 empty lines and asks again if I want to do a substitution.
How can I avoid these multiple substitution requests (at the same place)?
Hope I made myself clear :)
resolved it! I just had to check for a non space \S in the line before and the line after.
My new exe = 's/^.*\S\+.*\n\zs\(^\s*$\n\)\{'.b.'}\ze\s*\S\+/'.m.'/gc

Resources