ccalvert
ccalvert

Reputation: 4466

List strings not found with grep

I want to search in a file for specific words and then show only the words that were not found. So far, with my limited skills in this area, I can find which words are found:

egrep -w "^bower_components|^npm-debug.log" .gitignore

If my .gitignore file contained bower_components but not npm-debug.log it would return bower_components. I want to find out how to ask it to return only the part of the pattern that was not found. That is, I want it to return only npm-debug.log. I don't want to see all of the text from the file that does not match the search, only the single word from the file that was not found. How do I do that?

Upvotes: 2

Views: 3694

Answers (3)

thanasisp
thanasisp

Reputation: 5975

If you have just simple words like in your example, you could do it with two grep commands in one-liner. For example:

file:

first line
_another line
just another line
STRANGE LINE
last line

words:

first
last
row
other
^another
LINE$

we can first get the matched patterns

> grep -owf words file
first
LINE
last

and then we grep -v for them in words. Also add a uniq in the middle to remove any duplicates.

so finally we get patterns from words not matched in file:

> grep -owf words file | uniq | grep -vf - words
row
other
^another

Upvotes: 3

tink
tink

Reputation: 15213

I don't think this can be done with grep alone; here's a clumsy awk one-liner:

awk -v p1="npm-debug.log" -v p2="bower-component" 'BEGIN{a[p1]=0;a[p2]=0} $0 ~ p1 {a[p1]+=1}; $0 ~ p2 {a[p2]+=1}; END{for(i in a){if( a[i]==0){print i}}}' .gitignore

I'm passing the search pattern into awk as variables, pre-populating an array using the patterns as index, incrementing them if they match and only print ones that didn't have hits (still are 0).

Upvotes: 2

B.Ogles
B.Ogles

Reputation: 105

I don't have a one liner for you but a short script would work for your use case.

file=$1
shift
for var in "$@"
do
  found=`grep "^$var" $file`
  if [[ -z $found ]]
  then
   echo $var
  fi
done

Explanation, take the first argument as the file name, any subsequent arguments as strings to test for in the file. Loop through those arguments and test the result of the grep command to see if it returned empty. If it did then the string wasn't found and we print it to the console. Usage: [script name] .gitignore bower_components npm-debug.log

Upvotes: 3

Related Questions