Join non-matching lines - vim

I'm trying to join all lines who do not have a match
example text:
text Like
This is text of Line2
This is text of Line3
This is text of line4
Like text
This is text of line6
This is text of line7
Like
This is text of line9
All lines where "Like" is NOT present must join (with space between them)
end result:
text Like
This is text of Line2 This is text of Line3 This is text of line4
Like text
This is text of line6 This is text of line7
Like
This is text of line9
Can anyone help me?

First get rid of your trailing spaces:
:%s/\s\+$
Now here's an idea to join these lines:
:v/Like/normal VnkJ
Which should be self-explanatory. On every line that does not contain "Like",
enter visual line-wise mode, search for the next "Like" line (it reuses the
previous pattern), go one up and join.

:%v/Like/.,/Like/-1j
If you only want lines that start with Like, use ^Like instead.
And if you want to get rid of trailing spaces, do as sidyll wrote.
The code means:
% for all lines
v that do not match /Like/
., do from the current line (aka the (not) matching line)
/Like/-1 To the line bevor the next line matching /Like/
j join.
Since this is easier to understand and looks much nicer, I just add the compleate Version here:
$s/$/^MLike/|exec '%v/Like/.,/Like/-1j'|$d
It has the following addition:
$s/$/^MLike/
with ^M being an actual return (done via ^Vreturn)
this line adds a "Like" at the end, just in case you don't have one
exec '...'
Execs the v-line and protects the last | from being included in the repetition
$d
deletes the added 'Like' again.

I would use the following command.
:v/Like/,/\n.*Like\|\%$/j

Related

How to remove or replace words in VIM

How can I replace or delete words in VIM anything after
m/PH
Is so hard to use CTRL-v to delete them because I have tons of similar name from last point
My word structure in vim:
To answer your follow-up question
Is there any way Mr. To that without inside VIM ? ,. My file name is paragraph
if your file is named paragraph, the following sed command will do:
$ sed -i 's/\(m\/PH\).*/\1/' paragraph
If you mean the lines after the first occurence of m/PH then I would start a search from the first line to the first occurence and delete from this line on
:1;/m\/PH/,$ d
If you want to delete all characters in each line after m/PH then find this string, preserve it and "forget" anything else behind it
:%s/\(m\/PH\).*$/\1.

remove all empty lines from text files while keeping format

I have multiple notepad text files which contains one empty line (the last line of each file). I want to delete the empty line form all files. I tried different grep and awk lines but they didn't work plus they messed up the file format; all text are shown on one line instead of separate line. i also tried with notepad++ regex to find ^\s*$ and replace it with nothing, but it also didn't work.
Current text file looks like this:
apples
oranges
peaches
[empty line]
The output should be
apples
oranges
peaches
Ctrl+H
Find what: \R^$
Replace with: LEAVE EMPTY
check Wrap around
check Regular expression
Replace all
Explanation:
\R : any kind of linebreak
^ : begining of line
$ : end of line
Result for given example:
apples
oranges
peaches
If you want to delete the last line of the file, use sed '$d'. If you want to do that only when the last line is empty, use sed '${/^$/d;}' (This treats a line with some whitespace as a non-blank line, so you might prefer sed '${/^ *$/d;}' or some variant.
The "empty last line" may be a matter of interpretation. From the wikipedia "Newline" article:
Two ways to view newlines, both of which are self-consistent, are that newlines either separate lines or that they terminate lines. If a newline is considered a separator, there will be no newline after the last line of a file. Some programs have problems processing the last line of a file if it is not terminated by a newline. On the other hand, programs that expect newline to be used as a separator will interpret a final newline as starting a new (empty) line. Conversely, if a newline is considered a terminator, all text lines including the last are expected to be terminated by a newline. If the final character sequence in a text file is not a newline, the final line of the file may be considered to be an improper or incomplete text line, or the file may be considered to be improperly truncated.
In my little world, the Visual Studio Code editor takes the former view; vim the latter.

get lines between two marker patterns where ending pattern is in a specific column

I have to get lines between two marker patterns where the ending pattern has to be present in the third column only. The same ending pattern can be present in the first column as well but have to ignore this case & continue printing till the pattern is found in third column.
for example if the contents are like below & marker patterns are "start" & "stop" in the 3rd column
>Line1
>Line2 now stop
>start
>Line3
>Line4
>stop
>Line6
>Line7 now stop
>Line8
The output should be
Line3
Line4
stop
Line6
to get the lines between two patterns i found this
awk '/start/{flag=1;next}/stop/{flag=0}flag' input.txt
but that's doesn't apply in my case.Any hints how it can be done through awk or sed. Thanks in advance.
Editing my question as i came across a special case. If there are multiple occurences of the stop pattern & there is one occurence before the start pattern. How to handle this situation.
I have changed the input above to include this case.
You can use this awk command:
awk '$1=="start"{p=1; next} p && $3=="stop"{p=0} p' f
Line3
Line4
stop
Line6
This might work for you (GNU sed):
sed -rn '/^start/,/^(\S+\s){2}stop/{//d;p}' file

Search and append text at the end of the line

I have a file in which there is a command on each line. Within the command there is a line which is always P0......xml. I want to append that P0.... to the end of each line with a >> operator in front and .log at the end.
For example,
If a command looks like this:
abcdefg hijkl mno P0qrstuv.xml wxyz abc
I would like to make it:
abcdefg hijkl mno P0qrstuv.xml wxyz abc >> P0qrstuv.log
Please explain your answer as precisely as possible.
One solution would be to use the substitute command in Ex mode. This should do it.
:%s/\v(P0.+\.xml).*/& >>\1.log/
: puts you into Ex mode
% act on the whole file
s does the substitution
\v specifies that the regex will "very magic" and not the regular vim regex.
(P0.+\.xml) grouping of text the file name
& inserts what was matched
\1 inserts the first grouping (if you would have more than one you could do \2 \3 etc..)

VIM - Combine line from multiple files into single file

I'm trying to walk through my buffers list, select a single line from each buffer, and to have them all concatenated into a single file (or other buffer). As in:
file1
...
line2
...
file2
...
line2
...
file3
...
line2
...
and so on.
all into:
myfile
line2 (file1)
line2 (file2)
line2 (file3)
I can't seem to get my registers working, and bufdo is causing me heartache for some reason...
[clarification]
I was hoping I could use bufdo to walk through all my buffers, yank the second line from each, and append it into a register.
Then on another file, just paste the register contents into it (containing the second line from all of my buffers).
You should be able to do this with something like:
bufdo normal 2G"Ayy
which iterates through the buffers and runs the given command in normal mode. 2G jumps to the appropriate line, and "Ay yanks into register a, appending instead of overwriting (since the A is capitalized). Make sure register a is empty before you start!
You can use windo or tabdo if you have windows or tabs instead of buffers.

Resources