how to show lines between two same pattern? - sed

Hi I want to show lines between two same pattern.
I am using this command,
sed -n '/WORD1/,/WORD1/p' file.txt
This command only works if two pattern are different. But in my case both patterns are same.
So I am not getting proper output.
What is solution?
-----Vishal Patel

It works for me.
Here is the content of file.txt
outside
WORD1
inside
WORD1
outside
And the ouput of your command is
WORD1
inside
WORD1

Related

using sed remove the pattern lines

Can anyone help me solve this problem.
If the PATTERN starting and ending in the same line.
Remove the line including the PATTERN
joey people PATTERN we just had
PATTERN a lot of fun PATTERN
at my wedding
We will PATTERN
have more
PATTERN fun tomorrow PATTERN
all are welcome.
The above line should be like this after executing.
joey people PATTERN we just had
at my wedding
We will PATTERN
have more
all are welcome
Simple sed approach:
sed '/^PATTERN\(.*PATTERN\)*$/d' file
^ and $ - anchors, point to the start and end of the string respectively
^PATTERN\(.*PATTERN\)*$ - will match all lines which start and end(provided by optional capturing group \(.*PATTERN\)*) with PATTERN or contains PATTERN as a single word
An alternative using grep tool:
grep -v '^PATTERN\(.*PATTERN\)*$' file
-v (--invert-match) option, Invert the sense of matching, to select non-matching lines.

Printing all words that start with "#" using sed in BASH

I have a file with a lot of text, but I want to print only words that contain "#" at the beginning. Ex:
My name is #Laura and I live in #London. Name=#Laura. City=#London
How can I print all words that start with #?.I did this the following and it worked, but I want to do it using sed. I tried several patters, but I cannot make it print anything.
grep -o -E "#\w+" file.txt
Thanks
Use this sed command:
sed 's/[^#]*\(#[^ .]*\)/\1\n/g' file.txt
Explanation: we invoke the substitution command of sed. This has following structure: sed 's/regex/replace/options'. We will search for a regex and replace it using the g option. g makes sure the match is made multiple times per line.
We look for a series of non at chars followed by an # and a number of non-spaces #[^ ]*. We put this last part in a group \(\) and sub it during the replacement \1.
Note that we add a newline at the end of each match, you can also get the output on a single line by omitting the \n.

Extract CentOS mirror domain names using sed

I'm trying to extract a list of CentOS domain names only from http://mirrorlist.centos.org/?release=6.4&arch=x86_64&repo=os
Truncating prefix "http://" and "ftp://" to the first "/" character only resulting a list of
yum.phx.singlehop.com
mirror.nyi.net
bay.uchicago.edu
centos.mirror.constant.com
mirror.teklinks.com
centos.mirror.netriplex.com
centos.someimage.com
mirror.sanctuaryhost.com
mirrors.cat.pdx.edu
mirrors.tummy.com
I searched stackoverflow for the sed method but I'm still having trouble.
I tried doing this with sed
curl "http://mirrorlist.centos.org/?release=6.4&arch=x86_64&repo=os" | sed '/:\/\//,/\//p'
but doesn't look like it is doing anything. Can you give me some advice?
Here you go:
curl "http://mirrorlist.centos.org/?release=6.4&arch=x86_64&repo=os" | sed -e 's?.*://??' -e 's?/.*??'
Your sed was completely wrong:
/x/,/y/ is a range. It selects multiple lines, from a line matching /x/ until a line matching /y/
The p command prints the selected range
Since all lines match both the start and end pattern you used, you effectively selected all lines. And, since sed echoes the input by default, the p command results in duplicated lines (all lines printed twice).
In my fix:
I used s??? instead of s/// because this way I didn't need to escape all the / in the patterns, so it's a bit more readable this way
I used two expressions with the -e flag:
s?.*://?? matches everything up until :// and replaces it with nothing
s?/.*?? matches everything from / until the end replaces it with nothing
The two expressions are executed in the given order
In modern versions of sed you can omit -e and separate the two expressions with ;. I stick to using -e because it's more portable.

Replace 3 lines with another line SED Syntax

This is a simple question, I'm not sure if i'm able to do this with sed/awk
How can I make sed search for these 3 lines and replace with a line with a determined string?
<Blarg>
<Bllarg>
<Blllarg>
replace with
<test>
I tried with sed "s/<Blarg>\n<Bllarg>\n<Blllarg>/<test>/g" But it just don't seem to find these lines. Probably something with my break line character (?) \n. Am I missing something?
Because sed usually handles only one line at a time, your pattern will never match. Try this:
sed '1N;$!N;s/<Blarg>\n<Bllarg>\n<Blllarg>/<test>/;P;D' filename
This might work for you:
sed '/<Blarg>/ {N;N;s/<Blarg>\n<Bllarg>\n<Blllarg>/<test>/}' <filename>
It works as follows:
Search the file till <Blarg> is found
Then append the two following lines to the current pattern space using N;N;
Check if the current pattern space matches <Blarg>\n<Bllarg>\n<Blllarg>
If so, then substitute it with <test>
You can use range addresses with regular expressions an the c command, which does exactly what you are asking for:
sed '/<Blarg>/,/<Blllarg>/c<test>' filename

Multiline sed option?

I want to remove all the text between (and including) two strings in all the files in a directory. For an example, the files look something like this:
flag
bla bla bal
bla bla bla
endflag
etc..
This is what I'm doing with sed:
sed -i "s:flag.*endflag::m" *
However, the 'm' option is not part of sed. All the other Stack Overflow threads on this topic resort to using perl, awk, or a sed wrapper to accomplish this. Isn't there a way to tell sed to match newline characters?
In sed you can specify a range of lines where the range is a pattern marking the start of the range and another pattern marking the end of the range:
sed -i '/flag/,/endflag/d' *
You have to copy the text into the hold buffer first, than you can match \n like any other character. Normally, there is only one line in the hold buffer at a time, so \n is never part of the analyzed string. The following call first copies the first line into the hold buffer (1h) then appends all following lines into the hold buffer (1!H) and after having added the last line ($) does the replacement (s/).
sed -n '1h;1!H;${;g;s/flag.*endflag\n//g;p;}' foo.txt
To use alternate delimiters for range specifiers in sed, you have to escape the first one:
sed -i '\:<form:,\:</form>:d' *.aspx *.htm *.html