If conditions in awk

Hello Friends,

I need to find some CDRs in production servers whose 1st field value and 2nd field value = 1 and 11th looks like 45.123... where there are more than 3 digits after comma.so i wrote a one liner, something like below but does not work, however when i used first and second conditions it worked:

for file in `find . -type f -name "*.txt" -mtime -30 2>/dev/null`; do nawk -F\| '{if (($1==1) && ($2==1) && ($11~[0-9]*\.[0-9][0-9][0-9]*)) print $0}' $file; done
nawk: syntax error at source line 1
 context is
        {if (($1==1) && ($2==1) && >>>  ($11~[ <<< 
nawk: illegal statement at source line 1

Any suggestions, corrections welcome.

I couldnt find any other way to achieve this rather than awk..

Thanks in advance,
my best regards

Hi.

~ is expecting a regular expression, which should be between /.../

[root@wiki ~]# echo 123 | awk '$1 ~ /.[0-9]./'
123
[root@wiki ~]# echo abc | awk '$1 ~ /.[0-9]./'
[root@wiki ~]# 

I have just realised this and tried q min ago, but it didnt give me correct output:

nawk -F\| '{if ((($1==1) && ($2==1)) && ($11~/[0-9]*\.[0-9][0-9][0-9]*/)) print $0}' $file

in output the 11th field has all values like 12.34 rather than 12.345.....

1|1|1|sscmws-5400609|9840001131523171327|||20130113152317|scr|ccn-r|7.83|||3|784|3|7.83|971507857285|0|360||2|||CCN1|0
1|1|1|sscmws-5400611|9840001131524001329|||20130113152400|scr|ccn-r|5.48|||3|784|3|5.48|971509420582|0|360||2|||CCN1|0
.
.

should i put one more [0-9] ?? :slight_smile:

Replace the * with a + . Try:

awk -F\| '$1==1 && $2==1 && $11~/\.[0-9][0-9][0-9]+/' infile "$file"

or

awk -F\| '$1==1 && $2==1 && $11~/\.[0-9]{3,}/' infile

The latter will not work with mawk and needs the --posix option with gawk (if <4.0)

1 Like

Or use --re-interval , if you want to enable just that feature and if you don't want to disable all GNU awk extensions and those not allowed by POSIX.

1 Like

Thanks Scrutinizer as you remind me how to use combinations of {3} ..

I need something else, on another directory form of some warning CDRs is a bit different, the last field so i need to check sub fields of last field of CDRs and print them,

here a sample of CDR:
1|1|1|sscmws-5400746|9840001141031191292|||20130114103119|scr|ccn-r|43.98||ratedPrice and chargedAmount are different. rp:43.98 ca:43.980000000000004

i tried this but didnt work:

for file in `find . -type f -name "*.txt" -mtime -30 2>/dev/null`; 
do nawk -F\| '{split($NF,arr,":"); if ((arr[2+0]~/\.[0-9]{3,}/) || (arr[3]~/\.[0-9]{3,}/)) print $0}' $file; 
done

I could not parse only numerical part of second array adding "+0" and so i cant check second arrays which is "43.98" in sample,

for file in `find . -type f -name "*.txt" -mtime -30 2>/dev/null`
do 
  nawk -F\| '$NF ~ /.*:[0-9][0-9]*[.][0-9][0-9]$/'' $file
done

Hello Radoulov,

I have tested, yes {3,} didnt work for me, however when i tried

/\.[0-9][0-9][0-9]+/

it worked.

And let me share the result (i know it is not the optimum code but works pretty fine):

for file in `find . -type f -name "*.txt" -mtime -30 2>/dev/null`;
do nawk -F\| '{split($NF,arr,":"); if ((arr[2+0]~/\.[0-9][0-9][0-9]+/) || (arr[3+0]~/\.[0-9][0-9][0-9]+/)) print $0}' OFS="|" $file;
done

Thanks for your helps all!

BR

The above switches ( --posix and --re-interval )are supported by GNU awk only, it seems that you're using nawk.
On Solaris the POSIX awk supports re-interval by default:

bash-2.03$ echo 11 | nawk '/1{1,}/'
bash-2.03$ echo 11 | /usr/xpg4/bin/awk '/1{1,}/'
11