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

Using patterns on ranges?

Status
Not open for further replies.

ts5ad

Programmer
Apr 29, 2003
5
FI
Hi there

Im fairly new to AWK and was wondering if any1 could help with a dileema i currently have. Id like to be able to print uncommented lines which are between a specified range in a file.

I know how to output the range (/start pattern/, /stop pattern/), i know how to do the match (!~ /^#/) but i think awk treats them seperately and doesnt print the lines which satisfy both criteria.

Could someone suggest the correct method or what it is i am dong wrong?

Many thanks
 
Programming has its own language. It is more helpful lot of times if you show the code along with what you want to achieve.
 
For example, if a file contains:

This is an example file
foo

list
aaaaaa
bbbbb
#ccccc
ddddd
#eeeee
ffffff
end of list

bar
this is the end of this file

From the above output i would just like to print the uncommented lines between "list" and "end of list". How do i do this in awk? ihave tried the following line but it does not work.

awk ' /list/, /end/ !~ /^#/ '
 
interesting..... I don't think you can 'AND' them, but....

/pattern1/,/pattern2/ { $0 ~ /^[^#].*/ }


vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
sed is probably better in this case:
sed -n '/^#/!p' txtfile > newfile
 
hmmm, but rememebr i only want the lines in between list and end of list. will sed take this into account?
 
sed -n -e '/pat1/,/pat2/p' a | sed -n -e '/^#/!p'

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
Hi Vlad

Thanks but it returned nothing! The problem is i think that awk goes thru each line applying the pattern clause and THEN after this it looks at teh rest of any pattern amtching directives..?
 
try this one:

/pat1/,/pat2/ { if ($0 ~ /^[^#].*/) print }

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
Ok, you might need a longer awk program. I can try and test some codes later on, but here is the idea:

Use a loop
for ( x = 1; x <= NR; x++ )

&quot;if starts with list or end of list&quot; get the record numbers

print out those records between these two numbers&quot;

then apply sed or awk
 
A bit floppy, but try it see if it works

#! /bin/ksh

ss=`awk '/^list$/ { print NR }' $filename`
ee=`awk '/^end of list$/ { print NR }' $filename`
echo $ss
echo $ee

awk '{
for ( x > 1 ; x <= NR; x++ ) {
if (x> s && x < e) printf(&quot;%i\t%s\n&quot;, NR, $0) }
}
' s=$ss e=$ee $filename

exit
 
well........

this's inefficiently overkill and broken. Here's still inefficient, but fixed:

#! /bin/ksh

ss=`awk '/^list$/ { print NR }' $filename`
ee=`awk '/^end of list$/ { print NR }' $filename`
echo $ss
echo $ee

awk 'FNR >= s && FNR <= e' s=$ss e=$ee $filename

exit

#-------------------------------------------
Why do you need line numbers when you can use 'range patterns' I don't know......

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
my mind has been on the market all day. In comparison, tek-tips is like sanctuary. Hope this reply is not too unprofessional.

Back to the subject, printf gives you more flexibility, such as where they were located in the original file, though a little overkill.

but your second post works perfect
 
Hi guys

Thanks a lot for ur help. It was only gonna be a simple script anyway, the &quot;/pat1/,/pat2/ { if ($0 ~ /^[^#].*/) print } &quot; line u suggested vlad is sufficient for me

Cheers
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top