Need to use fgrep and egrep in a single command

I have a source file which is something like :

C/*M/  /            ***HMACCT   ** MONTH FOR CURRENT MINUS 14 CAL DAY
C/*D/  /            ***HMACCT   ** DAY FOR CURRENT MINUS 14 CAL DAY
C/*X/  /            ***HMACCT   ** CENTURY FOR CURRENT MINUS 14 CAL DAY
C/*Y/  /            ***HMACCT   ** YEAR FOR CURRENT MINUS 14 CAL DAY
C/+D/  /            ***HMCAG    ** DAY FOR CURRENT PLUS 1 BUSINESS DAY
C/+M/  /            ***HMCAG    ** MONTH FOR CURR PLUS 1 BUSINESS DAY
C/+T/  /            ***HMCAG    ** CENTURY FOR CURR PLUS 1 BUSINESS DAY
C/+Y/  /            ***HMCAG    ** YEAR FOR CURRT PLUS 1 BUSINESS DAY
C/=M/  /                        ** MONTH FOR CURRENT PLUS 2 CAL DAY
C/=D/  /                        ** DAY FOR CURRENT PLUS 2 CAL DAY
C/=Z/  /                        ** CENTURY FOR CURRENT PLUS 2 CAL DAY
C/=Y/  /                        ** YEAR FOR CURRENT PLUS 2 CAL DAY

I need to find out whether there is any line present with

*D or *X or *M

since there is a *, i am using fgrep to find exact match when i am searching for just one match

$fgrep "*M"  $SEQFILES/SUNIA.PJ008202.CARDLIB/DATECARD
C/*M/  /            ***HMACCT   ** MONTH FOR CURRENT MINUS 14 CAL DAY

however when i am trying to search for multiple matches

fgrep "*M |*D" $SEQFILES/SUNIA.PJ008202.CARDLIB/DATECARD

it does not work..no result
Any suggestions please !!

Hello gotamp,

You could try following solutions for same.
1st Solution:

grep -e '\*M' -e '\*D' -e '\*X'  Input_file

Output will be as follows.

C/*M/  /            ***HMACCT   ** MONTH FOR CURRENT MINUS 14 CAL DAY
C/*D/  /            ***HMACCT   ** DAY FOR CURRENT MINUS 14 CAL DAY
C/*X/  /            ***HMACCT   ** CENTURY FOR CURRENT MINUS 14 CAL DAY

2nd Solution:

awk '/\*M/||/\*D/||/\*X/'  Input_file

Output will be as follows.

C/*M/  /            ***HMACCT   ** MONTH FOR CURRENT MINUS 14 CAL DAY
C/*D/  /            ***HMACCT   ** DAY FOR CURRENT MINUS 14 CAL DAY
C/*X/  /            ***HMACCT   ** CENTURY FOR CURRENT MINUS 14 CAL DAY
 

Thanks,
R. Singh

1 Like

This should suffice:

grep '*[DXM]' file

Given the other character patterns on the lines, it may be better to anchor it to the two forward slashes:

grep '/\*[DXM]/' file
1 Like

Hi Ravinder,

Thanks for the help.
however this does not work for me..

aspsun11:dbh0000$grep -e '\*M' -e '\*D' -e '\*X' $SEQFILES/SUNIA.PJ008202.CARDLIB/DATECARD
grep: illegal option -- e
Usage: grep -hblcnsviw pattern file . . .

---------- Post updated at 07:50 AM ---------- Previous update was at 07:45 AM ----------

Many thanks Scrutinizer..
this is working absolutely fine.
:slight_smile:

Hello gotamp,

Glad that Scrutinizer's solution worked for you. Seems to be you have Solaris OS, it is always good practice to mention your OS details in your posts, you could try awk solution too which I have posted in POST#2. But on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk .

Thanks,
R. Singh

Yes it's Solaris, where you need the /usr/xpg4/bin/grep for the -e option.
Ravinder's awk solution works even with the old /usr/bin/awk
BTW it uses awk's || operator outside the /pattern/, where spaces are allowed for readability

awk '/\*M/ || /\*D/ || /\*X/' file

It is also possible to use the ERE (awk, egrep)-style | operator within the pattern

awk '/\*M|\*D|\*X/' file

or use a character set (like in any grep/egrep)

awk '/\*[MDX]/' file

But because awk uses the / as a pattern-delimiter, a literal / must be escaped in a pattern. That lowers readability

awk '/\/\*M\// || /\/\*D\// || /\/\*X\//' file

or

awk '/\/\*M\/|\/\*D\/|\/\*X\//' file

or

awk '/\/\*[MDX]\//' file

Last but not least there is the ERE-style ( ) sub-expression

awk '/\/\*(M|D|X)\//' file