How can I get a list of the subdirectories which contain a file whose name matches a particular pattern?
More specifically, I am looking for directories which contain a file with the letter 'f' somewhere occurring in the file name.
Ideally, the list would not have duplicates and only contain the path without the filename.
Best Answer
The above finds all files below the current directory (
.
) that are regular files (-type f
) and havef
somewhere in their name (-name '*f*'
). Next,sed
removes the file name, leaving just the directory name. Then, the list of directories is sorted (sort
) and duplicates removed (uniq
).The
sed
command consists of a single substitute. It looks for matches to the regular expression/[^/]+$
and replaces anything matching that with nothing. The dollar sign means the end of the line.[^/]+'
means one or more characters that are not slashes. Thus,/[^/]+$
means all characters from the final slash to the end of the line. In other words, this matches the file name at the end of the full path. Thus, the sed command removes the file name, leaving unchanged the name of directory that the file was in.Simplifications
Many modern
sort
commands support a-u
flag which makesuniq
unnecessary. For GNU sed:And, for MacOS sed:
Also, if your
find
command supports it, it is possible to havefind
print the directory names directly. This avoids the need forsed
:More robust version (Requires GNU tools)
The above versions will be confused by file names that include newlines. A more robust solution is to do the sorting on NUL-terminated strings: