# conditional multiple string matching

**URL:** <https://community.unix.com/t/conditional-multiple-string-matching/277292>\
**Category:** Shell Programming and Scripting\
**Created:** [November 13, 2010, 1:24am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292 "2010-11-13T01:24:36Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![kchinnam](https://community.unix.com/letter_avatar/kchinnam/32/5_5575768a8748004e209b776fc1b2916d.png) [@kchinnam](https://community.unix.com/u/kchinnam)\
**Post date:** [November 13, 2010, 1:24am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/1 "2010-11-13T01:24:36Z")

</div>

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.

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

```

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

```nohighlight
 
# How can I get this syntax working!?
$> find . -name \*.* -exec awk '(/b1b/ && /d1d/) && ( /a1a/ || /c1c/ ) {print FILENAME }' {} \;

```

```nohighlight
 
# But If I give only one condition its working. 
$> find . -name \*.txt -exec awk '/b1b/ {print FILENAME }' {} \;
input_xxx.txt

```

---

<div class="post-metadata">

**Author:** ![jim\_mcnamara](https://community.unix.com/letter_avatar/jim_mcnamara/32/5_5575768a8748004e209b776fc1b2916d.png) [@jim\_mcnamara](https://community.unix.com/u/jim_mcnamara)\
**Post date:** [November 13, 2010, 3:43am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/2 "2010-11-13T03:43:52Z")

</div>

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:

```nohighlight
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.

---

<div class="post-metadata">

**Author:** ![pravin27](https://community.unix.com/letter_avatar/pravin27/32/5_5575768a8748004e209b776fc1b2916d.png) [@pravin27](https://community.unix.com/u/pravin27)\
**Post date:** [November 13, 2010, 3:56am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/3 "2010-11-13T03:56:58Z")

</div>

Try this,

```nohighlight
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}} }' {} \;

```

---

<div class="post-metadata">

**Author:** ![rdcwayx](https://community.unix.com/letter_avatar/rdcwayx/32/5_5575768a8748004e209b776fc1b2916d.png) [@rdcwayx](https://community.unix.com/u/rdcwayx)\
**Post date:** [November 13, 2010, 6:17am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/4 "2010-11-13T06:17:19Z")

</div>

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:

```nohighlight
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

```

---

<div class="post-metadata">

**Author:** ![danmero](https://community.unix.com/letter_avatar/danmero/32/5_5575768a8748004e209b776fc1b2916d.png) [@danmero](https://community.unix.com/u/danmero)\
**Post date:** [November 13, 2010, 6:47am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/5 "2010-11-13T06:47:20Z")

</div>

```nohighlight
....
{if (a b c==111) {print FILENAME;exit}}' {} \;

```

Just another way 😉

---

<div class="post-metadata">

**Author:** ![becket](https://community.unix.com/user_avatar/community.unix.com/becket/32/235_2.png) [@becket](https://community.unix.com/u/becket)\
**Post date:** [November 13, 2010, 7:46am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/6 "2010-11-13T07:46:37Z")

</div>

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

```

---

<div class="post-metadata">

**Author:** ![danmero](https://community.unix.com/letter_avatar/danmero/32/5_5575768a8748004e209b776fc1b2916d.png) [@danmero](https://community.unix.com/u/danmero)\
**Post date:** [November 13, 2010, 8:18am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/7 "2010-11-13T08:18:52Z")

</div>

@becket !!

> [@kchinnam](#):
>
> I need to print fileNames that contains multiple search strings conditionally.

---

<div class="post-metadata">

**Author:** ![becket](https://community.unix.com/user_avatar/community.unix.com/becket/32/235_2.png) [@becket](https://community.unix.com/u/becket)\
**Post date:** [November 13, 2010, 9:31am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/8 "2010-11-13T09:31:18Z")

</div>

@danmero : this is exactly what my command does !

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

---

<div class="post-metadata">

**Author:** ![kchinnam](https://community.unix.com/letter_avatar/kchinnam/32/5_5575768a8748004e209b776fc1b2916d.png) [@kchinnam](https://community.unix.com/u/kchinnam)\
**Post date:** [November 13, 2010, 9:42am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/9 "2010-11-13T09:42:07Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![becket](https://community.unix.com/user_avatar/community.unix.com/becket/32/235_2.png) [@becket](https://community.unix.com/u/becket)\
**Post date:** [November 13, 2010, 9:44am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/10 "2010-11-13T09:44:57Z")

</div>

Sorry 🙂 My misunderstanding

---

<div class="post-metadata">

**Author:** ![Scrutinizer](https://community.unix.com/user_avatar/community.unix.com/scrutinizer/32/1216_2.png) [@Scrutinizer](https://community.unix.com/u/Scrutinizer)\
**Post date:** [November 13, 2010, 10:06am UTC](https://community.unix.com/t/conditional-multiple-string-matching/277292/11 "2010-11-13T10:06:45Z")

</div>

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:

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

```
