ni_hao
ni_hao

Reputation: 426

awk/grep/sed: find multiple patterns at one line in my files

I read a lot here about awk and variables, but could not find what I want. I have some files ($FILES) in a directory ($DIR) and I want to search in those files for all lines containing: both the 2 strings (SEARCH1 and SEARCH2). Using sh (/bin/bash): I do NOT want to use the read command, so I prefer awk/grep/sed. The wanted output is the line(s) containing the 2 strings and the corresp. file name(s) of the file(s). When I use this code, everything is ok:

FILES="news_*.txt"
DIR="/news"

awk '/Corona US/&&/Infected/{print a[FILENAME]?$0:FILENAME RS $0;a[FILENAME]++}' ${DIR}/${FILES}

Now I want to replace the 2 patterns ('Corona US' and "Infected') with variables in the awk command and I tried:

SEARCH1="Corona US"
SEARCH2="Infected"

awk -v str1="$SEARCH1" -v str2="$SEARCH2" '/str1/&&/str2/{print a[FILENAME]?$0:FILENAME RS $0;a[FILENAME]++}' ${DIR}/${FILES}

However that did not give me the right output: it came up empty (didn't find anything).

Upvotes: 0

Views: 1137

Answers (2)

RavinderSingh13
RavinderSingh13

Reputation: 133458

Since you have not shown sample of output so couldn't test it, based on OP's code trying to fix it.

awk -v str1="$SEARCH1" -v str2="$SEARCH2" 'index($0,str1) && index($0,str2){print (seen[FILENAME]++ ? "" : FILENAME ORS) $0;a[FILENAME]++}' ${DIR}/${FILES}

OR

awk -v str1="$SEARCH1" -v str2="$SEARCH2" '$0 ~ str1 && $0 ~ str2{print (seen[FILENAME]++ ? "" : FILENAME ORS) $0;a[FILENAME]++}' ${DIR}/${FILES}

OP's code issue: We can't search variables inside /var/ in should be used like index or $0 ~ str style.

Upvotes: 3

David C. Rankin
David C. Rankin

Reputation: 84541

It isn't 100% clear exactly what you are looking for, but it sounds like grep -H with an alternate pattern would allow you to output the filename and the line that matches $SEARCH1 or $SEARCH2 anywhere in the line. For example, you could do:

grep -H "$SEARCH1.*$SEARCH2\|$SEARCH2.*$SEARCH1" "$DIR/"$FILES

(note $FILES must NOT be quoted in order for * expansion to take place.)

If you just want a list of filenames that contain a match on any line, you can change -H to -l.

Upvotes: 1

Related Questions