2

So I would like to do grep -ril in a folder. I would want it to return only the top folder which gets a match.

To illustrate:

/tmp/: grep -ril "hello"

returns:

tmp1/banan/file
tmp1/banan2/file
tmp2/ape/file
tmp2/ape2/file

Expected result:

tmp1
tmp2

2 Answers 2

6

If you want to print only the first level directory, it will be more efficient to exit immediately after finding the first match under this directory. You can achieve this using -q which returns success for matching otherwise failure and when combined with -r it exits immediately when a match is found.

for d in */; do grep -qri "hello" -- "$d" && printf "%s\n" "$d"; done

-- is used to indicate the end of options, so whatever follows is file arguments, this protects form any directory named -something and could be interpreted as an option.

In case you would like the above for to match directories starting with ., consider setting shopt -s dotglob, see also this.

If you need to remove the trailing / from the output, you can use bash parameter expansion and, instead of "$d", print "${d%/}".

0
5

Directories don't match patterns for content; files do. What you seem to be asking is how to get the directories of files that match the pattern.

Strip off the path past the first component, and ensure the result is presented as unique values in sorted order, as you have specified

grep -ril "hello" | sed 's!/.*$!!' | sort -u

Replace the sort with awk '!h[$0]++' if you don't want to change the order of results

2
  • grep will scan the folders sequentially (you cannot get a result from tmp1, then another from tmp2, then back one from tmp1) so it would be better to use uniq instead of sort -u, as it won't need to keep everything in memory, and it will produce the results as they are printed
    – Ángel
    Commented Dec 3, 2020 at 0:51
  • Indeed, but because grep searches in directory order I wanted to be sure the output could be the expected tmp1, tmp2 rather than tmp2, tmp1. It would be possible to replace the awk with uniq, or the sed with cut -d/ -f1, as there are often multiple routes to a solution Commented Dec 3, 2020 at 7:52

You must log in to answer this question.

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