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 Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Korn Shell - question

Status
Not open for further replies.

tekcheck

Programmer
Sep 1, 2001
2
AU
Hey there,
I was just wondering how you could specify a range when reading a file in ksh?
Suppose I've got some data like so:

Name: Joe
Profession: Blah
Interests: Blah
<Other Text here>

Name: Dave
Profession: Blah
Interests: Blah
<Other Text here>

Now I'd like to read in the file and print out only the part on 'Joe'(the whole chunk - Name, Profession, etc), excluding Dave. Can this be done using grep/sed? I tried grep, but it only returns a single line. I know it can be done using awk, but is there some other way of going about it? Any suggestions?
Thanks for your time. Hope you have a safe and pleasant Easter.
 
tekcheck:

This is one way:


nawk ' BEGIN { p=0 }
{
if($1 ~ /^Name:/ && $2 ~ /Joe/) # turn printing on
{ p=1 }

if($1 ~ /^Name:/ && $2 !~ /Joe/) # turn it off
{ p=0 }

if(p==1)
{ print $0 }

} ' < tmpfile

It's easier to process multi-line records, if you have a well-defined start and stop. Suppose you have a blank line after each mult-line record. You could do this:

nawk ' BEGIN { p=0 }
{
if($1 ~ /^Name:/ && $2 ~ /Joe/)
{ p=1 }

if($0 ~ /^$/)
{ p=0 }

if(p==1)
{ print $0 }

} ' < tmpfile

 
Thanks for the prompt reply, olded..appreciate it.
But can it be done without using nawk/awk..i.e. in pure ksh?

Thanks again.
 
tekcheck,

As far as I know you will need to use some scripting language, awk or Perl or something, you could probably do it in sed (I say &quot;you&quot;, but I don't mean that *I* could do it in sed). Is there some reason you need to use the shell? Mike
&quot;Experience is the comb that Nature gives us after we are bald.&quot;

Is that a haiku?
I never could get the hang
of writing those things.
 
Hi Tekcheck,

You can do it(USING ONLY 'ksh')if you have FIXED NUMBER of fields for each entry (e.g., Name, profession, interest, phone, etc..).

Your entries go like this:

1
2
3
...
...
...

n Name: Joe
n+1 Profession: Blah
n+2 Interest: Blah
n+3
n+4
...
...
m Name: Joe
m+1 Profession: Blah
m+2 Interest: Blah
m+3
m+4
...
...

Use following steps:
--------------------

a) Use 'grep -n' to get the line # which matches your pattern (here Joe).

b) You might/ might not get multiple lines from the above command, depending on the occurance of the pattern.

c) Depending on the # of lines you are interested in (here 3 Name, Profession, Interest), use the following:

head -n filename | tail -1
head -n+1 filename | tail -1
head -n+2 filename | tail -1

This will print all the lines you are interested in.

Let me know if this answers your question.

Thanks,

Gyan


 
To get the range of text between Joe and Dave, excluding Dave, try

sed '/Name: Joe/,/Name: Dave/' input | sed '$d'

If there is a blank (or unwanted non-blank) line before Dave and you want it gone then try the following to remove the last two lines

sed '/Name: Joe/,/Name: Dave/' input | sed 'N;$!P;$!D;$d'

Cheers,
ND
 
Hi,

To get all the informations for a specific name, with sed you can do :

NAME=Joe
sed -n -e '
/^Name: '$NAME'/,/^Name:/{
x
/ON/{
x
/Name/q
x
}
s/^.*$/ON/
x
p
} ' input-file


With pure Ksh, you can do :

NAME=Joe
Flag=
while read rec
do
case &quot;^$rec&quot; in
&quot;^Name: $NAME&quot;*)
Flag=ON
echo $rec
;;
&quot;^Name:&quot;*)
[ -b &quot;$Flag&quot; ] && break
;;
*)
[ -n &quot;$Flag&quot; ] && echo $rec
;;
esac
done < input-file Jean Pierre.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top