2

I have a list of strings stringList, where I want to recursively search a directory and find all of the strings in stringList that did not appear in any search result. Right now, I have

cat stringList | grep -qrf /dev/stdin .

but then I do not sure where to go after that.

E.g. I have strings

foo

bar

baz

Only foo exists in a file in the directory. The script should return

bar

baz

2
  • Please, read MCVE Add sample input / expected output Mar 29, 2019 at 19:06
  • @GillesQuenot I added additional details, can you let me know if I need to add more?
    – Andrew
    Mar 29, 2019 at 20:56

2 Answers 2

2

Try:

string="foo
bar
baz"
echo "$string" | grep -v "$(find . -type f -exec cat {} + | grep -o "$string")"

This approach was chosen because it reads through the input files only once.

How it works

  • find . -type f -exec cat {} +

    This does a recursive search for files and prints their contents to stdout.

  • grep -o "$string"

    This selects any text matching the lines of $string.

  • echo "$string" | grep -v "$(find . -type f -exec cat {} + | grep -o "$string")"

    grep -v returns any line in string that is not found in one of the files from the recursive search.

Example

Consider a directory with files under it containing:

$ find . -type f -exec cat {} +
bar none
Here baz scaggs
behind bars
bazooka

If we add grep, we get just the matching words:

$ find . -type f -exec cat {} + | grep -o "$string"
bar
baz
bar
baz

Putting it all together, we determine that foo is the only word not in the files:

$ echo "$string" | grep -v "$(find . -type f -exec cat {} + | grep -o "$string")"
foo
1

You could do it with gawk as:

find . -type f -print0 | gawk -v listfile=/path/to/stringList '
  BEGIN{
    while ((getline string < listfile) > 0) list[string]
    RS="\0"
    while ((getline file < "/dev/stdin") > 0) ARGV[ARGC++] = file
    RS="\n"
  }
  {for (s in list) if (index($0, s)) delete list[s]}
  END {for (s in list) print s}'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .