Is substitution linking possible in the vi editor? - vim

I am trying to edit with two conditions in the vi.
example text)
hello world!
-apple watermelon
test text
two condition must be met.
start with -
I want to replace only the first letter of a word with a html tag (The first letter may not be the alphabet)
I tried substitution via pipe in vi, but i cant
Expected
hello world!
-<b>a</b>pple <b>w<b>atermelon
test text

You can use
:g/^-/s#\<\(.\)#<b>\1</b>#g
Meaning:
for every line that starts with - (:g/^-/)
substitute
the first character after a break (\<\(.\)) (while capturing it)
replace it with <b>\1</b> (\1 referencing the captured value)
multiple times per line (the g flag, remove this unless :set gdefault? returns nogdefault)

Related

How to add text before the first occurence of a character in Vim?

I have the text
af_ZA_work_013_A;135.300;150.203;Spreker-A;;;[no-speech] #mm
af_ZA_work_013_A;135.300;150.207;Spreker-B;;;[no-speech] #something
I want to add .wav before the first ; in each line, so I would get
af_ZA_work_013_A.wav;135.300;150.203;Spreker-A;;;[no-speech] #mm
af_ZA_work_013_A.wav;135.300;150.207;Spreker-B;;;[no-speech] #something
How can I do this?
s/search_regex/replace_regex/ will linewise execute your find and replace.
By default, this is done only on the current line, and only on the first match of search_regex on the current line.
Prepending % (%s/search/replace/) will execute your find and replace on all lines in the file, doing at most one replacement per line. You can give ranges (1,3s will execute on lines 1-3) or other line modifiers, but this isn't relevant here.
Appending g (s/search/replace/g) will do multiple replaces per line. Again, not relevant here, but useful for other scenarios.
You can search for ; and replace with .wav; (there are ways to keep the search term and add to it using capture groups but for one static character it's faster to just retype it).
TL;DR: :%s/;/.wav;/ does what you want.

inserting a number from stdout into a string from stdout

I'm working on a Linux terminal.
I have a string followed by a number as stdout and I need a command that replaces the middle of the string by the number and writes the result to stdout.
This is the string and number: librarian 16
and this is what the output should be: l16n
I have tried using echo librarian 16|sed s/[a-z]*/16/g and this gives me 9 999 the problems are that it replaces every letter separitaly and that it also replaces the first and last letter and that I can't make it use the number from stdout.
I have also tried using cut -c 1-1 , sed s/[^0-9]*//g and cut-c 9-9 to generate l, 16 and n respectively but I can't find how to combine their outputs into a single line.
Lastly I have tried using text editors to copy the number and paste it into the string but I haven't made much progress since I don't know how to use editors directly from the command line.
So what you want is to capture the first letter, the last letter and the number while ignoring the middle.
In regex we use ( and ) to tell the engine what we want to capture, anything else simply gets matched, or "eaten", but not captured. So the pattern should look like this:
([a-z])[a-z]*([a-z]) ([0-9]+)
([a-z]) to capture the first letter
[a-z]* to match zero or more characters but not capture. We choose "*" here because there might not be anything to match in the middle, like when there are two or less letters.
([a-z]) to capture the last letter.
to "eat" the whitespace.
([0-9]+) to capture the number. We use + instead of * because we require a number at this position.
sed uses a different syntax for some fo these constructs so we'll use the -E flag. You could do without it but you'd have to escape the ()+ characters which IMO makes pattern a little bit confusing.
Now, to retrieve the captured content, we have to use an engine-specific sequence of characters. sed uses \n where n is the number of the capturing group, so our final pattern should look like this:
\1\3\2
\1: First letter
\3: Number
\2: Last letter
Now we put everything together:
$ echo librarian 16|sed -r 's/([a-z])[a-z]*([a-z]) ([0-9]+)/\1\3\2/g'
l16n

How to find and remove part of word in vim?

I'm new into vim, I have hug text file as follow:
ZK792.6,ZK792.6(let-60),cel-miR-62(18),0.239
UTR3,IV:11688688-11688716,0.0670782
ZC449.3b,ZC449.3(ZC449.3),cel-miR-62(18),0.514
UTR3,X:5020692-5020720,0.355907
First, I would like to get delete all rows with even numbers (2,4,6...).
Second, I would like to remove (18) from entire file. as a example:
cel-miR-62(18) would be cel-miR-62.
Third: How can I get delete all parentheses including it's inside?
Would someone help me with this?
For the first one:
:g/[02468]\>/d
where :g matches all lines by the regex between the slashes and runs d (delete line) on the matching lines. The regex is quite easy to read, the only interesting symbol there is perhaps the \>, which matches end of a word.
For the second question:
:%s/\V(18)//g
where % is the specification meaning "all lines of the file", s is the substitute command, \V sets the "very nomagic" mode of regexes (not sure what your default is, you might not need this) and the final g makes vim substitute all occurrences on each line (with an empty string, the one between slashes). Make sure that :set gdefault? prints nogdefault (the default setting of gdefault), otherwise, drop the final g from the substitute command.
To remove every even line (or every other line):
:g/^/+d
To remove every instance of (18):
:%s/(18)//g
Remove all the parenthetical content:
:%s/(.\\{-})//g
Note: the pattern in third answer is a non-greedy match.

Sublime Text 2 block editing transform

how to transform text block to get it in one line
for example
Hello
Sublime
Text
Editor!
should become
Hello Sublime Text Editor!
??
Thanks!
You don't need a regular expression to do this. First, select the text:
Then hit CtrlJ on Windows/Linux or ⌘J on OS X to join the lines together:
This can be done for example by running a Perl regular expression replace searching for (?:[\t ]*\r?\n[\t ]*)+ and using a single space character as replace string.
(?:...) is a non marking group.
[\t ]* finds 0 or more tabs or spaces.
\r?\n finds an optionally present carriage return and a line-feed.
And the + means 1 or more times of the regular expression in the non marking group which in other words finds optionally existing trailing whitespaces at end of a line, the line termination and optionally existing whitespaces at beginning of next line.

How to replace characters until matching character sequence?

I know that in command mode, ct{char} removes all text from current cursor position till next matching {char}, which can then be replaced by continuing to type.
For example, suppose the text is:
abcdefgh
and cursor is on b, then typing ctg will remove bcdef, which can be replaced by continuing to type.
But this works only for a single matching character. Is it possible to do this by matching a character sequence, for example, using gh instead of g, in above example?
Note: I know that the s/// could be used, but this is a little faster, and more convenient.
Yes. Use the search command:
c/gh
The search is a motion for the previous command. So it will delete characters until if finds a gh string.

Resources