Including Hash / in sed command filter

Hello All,

I want to print data in between two lines in a file sample.txt through more or cat command on the screen. For that I am using below sed command to give the BEGIN and END text.

Content of sample.txt

server01:~ # cat /proc/mdstat

Hello this is a text message 1
Hello this is a text message 2
Hello this is a text message 3
Hello this is a text message 4
Hello this is a text message 5
server01:~ # df -k

TESTING 1
TESTING 2
TESTING 3
TESTING 4
TESTING 5
server02:~ # df -k

Command and its output:

server01:~ # more sample.txt | sed -n -e '/server01:~ # cat/,$p' | sed -e '/server01:~ # df -k/,$d'

Hello this is a text message 1
Hello this is a text message 2
Hello this is a text message 3
Hello this is a text message 4
Hello this is a text message 5

The above method is working fine but since I may have more cat text for server01 in sample.txt so I want to include complete text 'server01:~ # cat /proc/mdstat' in the BEGIN or END in between the sed / / for exact matching. But it gives error when I put like below because the matching string itself contains Hash (/) :

server01:~ # more sample.txt | sed -n -e '/server01:~ # cat/proc/mdstat/,$p' | sed -e '/server01:~ # df -k/,$d'

Please suggest the way forward

I'm sorry I don't understand your request at all.

If you're after a solution to include a slash / in the address, you can

  • escape it ( \/ )
  • use another character for the address delimiters. man sed :c

When you try to match strings with sed you need to distinguish between characters and metacharacters. Characters only match themselves, i.e.

sed -n '/a/p' /some/file

will print every (line containing an) "a" because /a/ matches only an "a" and nothing else.

But there are characters that do not match these same characters directly but influence the way other characters match something. These are called metacharacters and a "regular expression" usually consists of a mixture of characters and metacharacters. Here:

sed -n '/aa*z/p' /some/file

the expression searched for to print the line is /aa*z/ and the asterisk makes the "a" in front of it optional: it makes that any number (including zero) of the character before is matched. Here are some strings which would be matched by this expression:

az
aaz
aaaz
aaaaz
...

The one string NOT matched by the expression is this: aa*z , because the asterisk - unlike the "a" - doesn't match itself, only the way other characters (in this case the "a") match something.

In general, if you want to use a metacharacter as normal character you need to [i]escape[/icode] it. To escape it means you put a backslash ("\") in front of it:

sed -n '/aa\*z/p' /some/file

This changes the "*" to be a normal character and the only string this expression will match now is:

aa*z

and nothing else. The slash ("/") is also a metacharacter because it is used to mark beginning and end of a regular expression. In the above /aa*z/ it is not encluded in the string we searched for but acts only as a separator, similar to quotes like "this", which don't belong to the word they surround either. And therefore it needs to be escaped the same way as the asterisk:

sed -n -e '/server01:~ # cat/proc/mdstat/,$p'      # wrong
sed -n -e '/server01:~ # cat\/proc\/mdstat/,$p'                # correct

You need to do this with all metacharacters in your search expression. The most used ones are:

/
*
[
]
.

Btw., you should NOT use more for this purpose and you do not need to use separate sed calls for this:

server01:~ # more sample.txt | sed -n -e '/server01:~ # cat/proc/mdstat/,$p' | sed -e '/server01:~ # df -k/,$d'

write it like this instead:

server01:~ # sed -n -e '/server01:~ # cat/proc/mdstat/,$p' -e '/server01:~ # df -k/,$d' sample.txt

or even like this - ";" is used as separator between consecutive commands:

server01:~ # sed -n -e '/server01:~ # cat/proc/mdstat/,$p;/server01:~ # df -k/,$d' sample.txt

I hope this helps.

bakunin

Hello,

Thanks for your valuable and detailed input. This has worked for me !! Thanks mate

sed -n -e '/server01:~ # cat \/proc\/mdstat/,$p'                # correct

--- Post updated at 11:58 AM ---

You understood correctly and your suggestion has worked for me. Thanks dear

WHAT is not working? Sorry, but i cannot see you monitor and if i should explain to you something i need to know what it is. Post your screen output (surrounded by CODE-tags) so that i can see what you have done and what the result was.

more is a paginator program, nothing more, nothing less. That means: if you have a long file and you type:

cat /this/file

it would rush all the lines through you terminal window at a high speed (far too fast to read along) and only the last lines would finally be visible, all the lines before would have scrolled off the screen. Instead using

more /this/file

will pause after each screen full of text and only continue (for exactly one other screen full) after you press a key. This is what more does. I can't see how that relates to your problem at all.

I hope this helps.

bakunin

Hello Bakunin,

Sorry it was my bad. The command didn't work first due to some extra space needed which I added and now it is working. So your solution was perfect for my problem. Thanks.