Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SED-How to select single string only and not both? 2

Status
Not open for further replies.

RFC1795

IS-IT--Management
Feb 13, 2003
76
US
Hi,

I've searched the boards and not finding the answer to my problem. I'm probably using the wrong keywords ;-)

Anyhow, here's an example of the problem. As an example, I have a file which contains the following:

entry0/1
blah blah blah
#
entry0/12
other blah blah stuff
#
entry2/10
boring stuff here
#


Using sed I want to selectivly print the lines between the word "entryX/Y" and the symbol "#"

Eg:
root[/tmp] $ cat test.txt | sed -n "\?entry2/10?,/#/p"
Outputs:
entry2/10
boring stuff here
#


Thats good, now for the problem one:

root[/tmp] $ cat test.txt | sed -n "\?entry0/1?,/#/p"
Output:
entry0/1
blah blah blah
#
entry0/12
other blah blah stuff
#


I tried the sed man page but there doesn't seem to be a flag to say word only like grep -w for instance.

Any ideas?

Thanks..TJ
 
And this ?
root[/tmp] $ sed -n '\?^entry0/1$?,/^#/p' test.txt


Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
Damn you guys are good :) I still have so much to learn. *sigh*

Thanks for that.

TJ
 
Mmm ... It seems I've hit a snag. When using a variable I seem to skip some lines... not sure why.

I'm now testing at the command line and the moment to try figure it out. I'm not having luck introducing the variable too well.

In the example test.txt file I have an the following extra lines:

entry0/12
other blah blah stuff
#
entry0/12.1.1
adress
code
#

This works:
root[/tmp] $ sed -n '\?^entry0/12.1.1$?,/^#/p' test.txt
entry0/12.1.1
adress
code
#

This doesn't:
root[/tmp] $ ENT="entry0/12.1.1" ; echo "$ENT" ; sed -n '\?^$ENT?,/^#/p' < test.txt
Output: (I have included the echo to show the variable is taking yet does not show up)
entry0/12.1.1

Again without variable:
root[/tmp] $ ENT="entry0/12.1.1" ; echo "$ENT" ; sed -n '\?^entry0/12.1.1?,/^#/p' < test.txt
Output:
entry0/12.1.1
entry0/12.1.1
adress
code
#

I've tried different quote marks on the ENT='entry0/12.1.1' etc... also tried things like sed -n '\?^${ENT}?,/^#/p' ... and with just ENT="entry0/12"

I'm lost... :(

TJ
 
Ok, I thought I'd try it in a script to debug problem so came up with the following now.

Script is called trun.sh which contains the following: (I've listed two versions of it where one does not contain a $ and the other does .. see the bold bit)

Ver1 :-
for ENT in `cat test.txt | grep entry`
do
echo "-------"
cat test.txt | sed -n "\?^$ENT?,/^#/p"
done

Outputs the following:

-------
entry0/1
blah blah blah
#
entry0/12.1.1
adress
code
#
entry0/12
other blah blah stuff
#
-------
entry0/12.1.1
adress
code
#
-------
entry0/12.1.1
adress
code
#
entry0/12
other blah blah stuff
#
-------

Ver2 :-
for ENT in `cat test.txt | grep entry`
do
echo "-------"
cat test.txt | sed -n "\?^$ENT$?,/^#/p"
done

Output is:

root[/tmp] $ ./trun.sh
-------
sed: command garbled: \?^entry0/10,/^#/p
-------
sed: command garbled: \?^entry0/12.1.10,/^#/p
-------
sed: command garbled: \?^entry0/120,/^#/p
-------
sed: command garbled: \?^entry2/100,/^#/p

Hope that helps more than my previous post.

Thanks... TJ
 
OK, its a shell quoting problem.
You may try this:
[tt]sed -n '\?^'"$ENT"'$?,/^#/p' test.txt[/tt]

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
Thanks PHV,

These quote things always catch me out... and there's so many ways to try it ;-)

It's looking a lot better .. but spotted something else while building this ... I'm still busy trying a few things before I come running back for help .. but if you know off hand why this is then it might help me.

In my test.txt file, if the line with entryX/Y.a.b.c has something afterwards, like:

entry10/12.1.2 Jones,A

Then it doesn't seem to like it either... pretty odd. Something to do with the $ ... not sure .. I'll report back or call back if i get stuck :) (But feel free to explain if you know why this is so)

Thanks... TJ
 
Code:
awk '$0 ~ "^" entry "$", /^#/' entry="entry0/1" test.txt
Let me know whether or not this helps.

If you have nawk, use it instead of awk because on some systems awk is very old and lacks many useful features. Under Solaris, use /usr/xpg4/bin/awk.

For an introduction to Awk, see faq271-5564.
 
In my test.txt file, if the line with entryX/Y.a.b.c has something afterwards, like:

entry10/12.1.2 Jones,A

Then it doesn't seem to like it either
[tt]
awk '$0 ~ "^" entry "([ \t]|$)", /^#/' entry="$ENT" test.txt
[/tt]
 
Great suggestions ... :) Worth trying a different angle and broadening the mind a bit.

Getting closer ...

If I do a debug and grep + only I get something like this now:

+ nawk $0 ~ "^" entry "([ \t]|$)", /^#/ entry=entry10/12.1.1 test.txt
+ nawk $0 ~ "^" entry "([ \t]|$)", /^#/ entry=Jones,A test.txt
etc.

So output is displaying like this now:

-------
entry10/12.1.1 Jones,A
address
#
------- <- I figure the missing entry statement here was when it was looking up Jones,A
-------
entry0/12.1.2
Tel xxxxx
#
entry0/12.1.2 Jones,B <- Here it grabbed both entries instead of one at a time
code
#
-------

Whew ... brain needs a rest from this or something. I'm sure its something simple I need to do .. just to find it hehe

Cheers... TJ
 
nawk '$1==entry,/^#/' entry=entry10/12.1.1 test.txt

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
Hi PHV,

That one has the same problem:

root[/tmp] $ nawk '$1==entry,/^#/' entry=entry0/12.1.2 test.txt
Output:
entry0/12.1.2
Tel xxxxx
#
entry0/12.1.2 Jones,B
code
#

Are there any flags in awk that forces it to use only the one exact variable/string supplied?

My awk knowledge is pretty limited to : awk '{print $x}' etc hehe... :)

Cheers... TJ
 
And this ?
nawk '
$1==entry{++f}
f
/^#/{--f}
' entry=entry0/12.1.2 test.txt

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
Code:
$0 == entry, /^#/
If that doesn't do it, then I may have misunderstood what you want. In that case, give me a good example. Show the exact contents of a file that includes all the forms the data can take. Then show the exact output you want for several different search strings.
 
Hi Futurelet,

Thanks for helping, I tried a few different methods but I never got far with that line.

This is a better sample I suppose of what I want to do. I have a plain text file which contains entries like this:

entry0/1
address-code1
field1
#
entry0/1 Adams,D.C
address-code1
address-code2
field1
field2
#
entry0/1.1 Adams,D.C
Telxxxxxxx
Mobxxxxxxx
#
entry6/1.1
field1
#
entry6/1.10
Telxxxxxxx
Mobxxxxxxx
field1
#
entry6/1.15 Adams,GK
address-code2
field6
#

My aim is to create a script that displays the data between the word "entryXX/YY.a.b.c <and other possible data>", and the symbol "#" Usually I'd just use sed getting it to display between the word "entry" and "#", but the I'm hitting a problem with the extra characters after the word "entry"

This snipit of data is then worked on further in the script. For now my only problem is capturing the data (using a variable) between the two markers without it duplicating.

Hope this make sense :)

Cheers... TJ
 
For entry="entry0/1 Adams,D.C", the output is
[tt]
The data is:
address-code1
address-code2
field1
field2
[/tt]

For entry="entry0/1", the output is
[tt]
The data is:
address-code1
field1
[/tt]

Save the code in file "between.awk" and run with
[tt]awk -v entry="entry0/1" -f between.awk data[/tt]

Code:
# The variable "entry" is set on the command line;
# for example:
# awk -v entry="entry0/1 Adams,D.C" between.awk data

$0 == entry { capturing=1; next }

capturing && /^#/ { capturing = 0
  gsub( /^\n|\n$/, "", data )
  print "The data is:"
  print data
  data = ""
}

capturing { data = data "\n" $0 }
 
Hi Futerlet,

Sorry but that never worked for me. I kept getting the following error:

awk: syntax error near line 1
awk: bailing out near line 1

I'm going to try a few more things and come back to you. I'm even thinking that the problem I'm experiencing may also be a simple grep issue also.

Will advise soon as I know what I'm doing ;-)

Cheers... TJ
 
Copy and paste in file "between.awk":


# The variable "entry" is set on the command line;
# for example:
# awk -v entry="entry0/1 Adams,D.C" between.awk data

$0 == entry { capturing=1; next }

capturing && /^#/ { capturing = 0
gsub( /^\n|\n$/, "", data )
print "The data is:"
print data
data = ""
}

capturing { data = data "\n" $0 }




Run it with

awk -v entry="entry6/1.1" -f between.awk test.txt

If that doesn't work, try:

nawk -v entry="entry6/1.1" -f between.awk test.txt


There are no syntax errors in the program. I tested it with Awk, Mawk, and Gawk. Are you running under Solaris? If so, use /usr/xpg4/bin/awk.

Vlad, can you detect any syntax errors?
 
stating "da obvious"... make sure there're no ^M in the script file - the usual gotcha of transfering files....
Other than that - it looks kosher to me.

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
Yes, but if he copies and pastes on a Unix or Linux system, I don't see how there could be a ^M.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top