Re: Slightly OT: How to grep for two different things in a file

From: Andreas Kusalananda Kähäri <andreas.kahari_at_abc.se>
Date: Wed, 07 Sep 2022 22:56:09 UTC
On Wed, Sep 07, 2022 at 06:00:36PM -0400, Aryeh Friedman wrote:
> I have 2 patterns I need to find in a given set of files.  A file only
> matches if it contains *BOTH* patterns but not in any given
> relationship as to where they are in the file.   In the past I have
> used piped greps when both patterns are on the same line but in my
> current case they are almost certainly not on the same line.
> 
> For example my two patterns are "tid" (String variable name) and
> "/tmp" [String literal] (i.e. the full string is the concatenation of
> the two patterns I would do:
> 
> grep -Ri tid src/java|grep -i /tmp
> 
> But since /tmp is in a symbolic constant defined elsewhere (in a
> different Java file) I need to find programmatically either the name
> of the constant (has different names in different classes) and then do
> the piped grep above with it or I need to look for the two patterns
> separately and say a file is only accepted if it has both.
> 
> P.S. The reason for this is I am attempting to audit my code base to
> see what classes leave behind orphaned temp files.
> 
> -- 
> Aryeh M. Friedman, Lead Developer, http://www.PetiteCloud.org

I don't see an example of the stuff you talk about after "But since
/tmp is in a symbolic constant defined elsewhere..." so I don't fully
understand what that would involve and will therefore ignore it.
Instead, the following answers the subject question, "How to grep for
two different things in a file".

	find src/java -type f \
		-exec grep -qF 'tid' {} \; \
		-exec grep -qF '/tmp' {} \; \
		-print

or call an in-line script,

	find src/java -type f -exec sh -c '
		for pathname do
			if grep -qF "tid" "$pathname" &&
			   grep -qF "/tmp" "$pathaname"
			then
				printf "%s has both tid and /tmp\n" "$pathname"
			fi
		done' sh {} +

In any case, the point is to first test a file for one of th strings,
and if that succeeds, test the same file for the other string, then
report the file as accepted if that other string was also found.

See grep(1) for what -F and -q does.  I dropped the -i option as I
assumed that you actully know the case, at least when looking for
"/tmp".

Also, https://unix.stackexchange.com/questions/389705


-- 
Andreas (Kusalananda) Kähäri
SciLifeLab, NBIS, ICM
Uppsala University, Sweden

.