conditional multiple string matching

I need to print fileNames that contains multiple search strings conditionally.

Condition: Any file in the folder that has search strings
---> (b1b && d1d) && ( a1a || c1c ).

i.e File should have both (b1b AND d1d) AND (either a1a or c1c).

Where && is logical AND
|| is logical OR.

input_xxx.txt
a1=a1a
b1=b1b
c1=c1c
d1=d1d

Here is what I have so far, but its not working.

 
# How can I get this syntax working!?
$> find . -name \*.* -exec awk '(/b1b/ && /d1d/) && ( /a1a/ || /c1c/ ) {print FILENAME }' {} \;
 
# But If I give only one condition its working. 
$> find . -name \*.txt -exec awk '/b1b/ {print FILENAME }' {} \;
input_xxx.txt

What you show as code means:
print a file name when a single record has 3 out of 4 search strings.

The example that works tells me that this is not what is in the data, nor is it what you mean. I am guessing that what you want is a list of files that have 3 out of 4 sprinkled somewhere in the file, not all on the same line. This works in ksh:

grep -l -e 'a1a' -e 'c1c' <( grep -l 'b1b' $(find . -name '*.txt' -exec grep -l 'd1d' {} \;  ))
#expanded out
grep -l  'b1b' $(find . -name '*.txt' -exec grep -l 'd1d' {} \; ) > t.lis
grep -l  -e 'c1c' -e 'a1a' $( < t.lis )

This is process substitution - feeding the output of process a into process b
My bash version == 2.05, so I can't test this in bash, just ksh.

Try this,

find . -name "input_*.txt" -exec awk '{if(/b1b/){flg++};if(/d1d/){flg++};if(/a1a/ || /c1c/){flg1++} {if(flg==2 && flg1>=1){print FILENAME;flg=0;flg1=0}} }' {} \;

For pravin27's code, if the input txt file has two b1b, but no d1d, it will also export the filename. If there are more b1b, d1d, (more than 2), if will not list it.

Here is the fix:

find . -name "*.txt" -exec awk '
/b1b/{a=1}
/d1d/{b=1}
/a1a/ || /c1c/ {c=1}
{if (a==1&&b==1&&c==1) {print FILENAME;exit}}' {} \;
./infile.txt
1 Like
....
{if (a b c==111) {print FILENAME;exit}}' {} \;

Just another way :wink:

find ./   \( -name "*b1b*"  -name "*d1d*" \) -a  \( -name "*a1a" -o -name "*c1c*" \)

@becket !!

@danmero : this is exactly what my command does !

( b1b && d1d ) && ( a1a || c1c ) ...

Thanks a lot for everyone. test script is working.. I am testing it in a larger context.

I am hoping there is no better way of doing this kind multiple string searching sprinkled in a file conditionally. If there is one please share.

---------- Post updated at 09:42 AM ---------- Previous update was at 09:38 AM ----------

becket,
What you are trying to help me with is searching for multiple strings in the file Names. But my question was to find them in the file contents.

Please read the question and test data I gave carefully.

Sorry :slight_smile: My misunderstanding

Well it is quite understandable since the OP's post is a bit contradictory IMO. I am assuming the OP is looking for what Jim suggested in post #2. Then this could be used in the find exec:

awk '/b1b/{a=1}/d1d/{b=1}/a1a|c1c/{c=1} END{if(a&&b&&c)print FILENAME}'