1

I am trying to search for files with specific text but excluding a certain text and showing only the files.

Here is my code:

grep -v "TEXT1" *.* | grep -ils "ABC2" 

However, it returns: (standard input)

Please suggest. Thanks a lot.

The output should only show the filenames.

5
  • I don't understand your first sentence. Can you rephrase it? Are you looking for filenames that do not contain TEXT1, or files that do not contain TEXT1 in their content? Commented Jun 9, 2021 at 10:10
  • have a look at the following : superuser.com/questions/537619/… Commented Jun 9, 2021 at 10:11
  • hi , I am looking for file that does not containt TEXT1 and contains ABC2 Commented Jun 9, 2021 at 10:12
  • thanks.. jcupers, however the grep need to only show the filenames.. Commented Jun 9, 2021 at 10:15
  • this works : grep -P '(?=^((?!bar).)*$)foo' ... output filename:found term. you can cut it up if needed Commented Jun 9, 2021 at 10:23

2 Answers 2

2

Here's one way to do it, assuming you want to match these terms anywhere in the file.

grep -LZ 'TEXT1' *.* | xargs -0 grep -li 'ABC2' 
  • -L will match files not containing the given search term
    • use -LiZ if you want to match TEXT1 irrespective of case
  • The -Z option is needed to separate filenames with NUL character and xargs -0 will then separate out filenames based on NUL character


If you want to check these two conditions on same line instead of anywhere in the file:

grep -lP '^(?!.*TEXT1).*(?i:ABC2)' *.* 
  • -P enables PCRE, which I assume you have since linux is tagged
  • (?!regexp) is a negative lookahead construct, so ^(?!.*TEXT1) will ensure the line doesn't have TEXT1
  • (?i:ABC2) will match ABC2 case insensitively
  • Use grep -liP '^(?!.*TEXT1).*ABC2' if you want to match both terms irrespective of case
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks sundeep. Your solution work. Also thanks for the explaination :) Highly appreciated
1
(standard input) 

This error is due to use of grep -l in a pipeline as your second grep command is reading input from stdin not from a file and -l option is printing (standard input) instead of the filename.

You can use this alternate solution in a single awk command:

awk '/ABC2/ && !/TEXT1/ {print FILENAME; nextfile}' *.* 2>/dev/null 

4 Comments

Thanks for sharing nice code sir, could you please do let me know why we need *.* here? Can't be just * used here? Will be grateful if you could explain this one, thank you.
I used *.* because OP also had it, assuming filenames have extensions with . in filenames
oh ok, in case of * files with . will not be picked up? Sorry haven't tested it yet.
Files with . will also be picked up with just * but it will also pickup directories whereas *.* is more restrictive to match filenames with extensions only.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.