Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding directories that contains given files?

I hope this is an interesting question.. I want to find a directory that contains all the given files .. Until now what I have done is as follows

Find multiple files in unix...

find . -type f \( -name "*cache" -o -name "*xml" -o -name "*html" \)

reference : http://alvinalexander.com/linux-unix/linux-find-multiple-filenames-patterns-command-example

Finding only directories containing given files...

find . -type f -name '*.pdf' |sed 's#\(.*\)/.*#\1#' |sort -u

Reference : http://www.unix.com/unix-for-dummies-questions-and-answers/107488-find-files-display-only-directory-list-containing-those-files.html

How can I make a command that will give me a directory which contains all the given files... ( The files must be in given directory only not in sub directory .. and all the files given in a list must be present )

Want to search for WordPress theme directories

like image 925
VIVEK SEDANI Avatar asked Feb 06 '15 10:02

VIVEK SEDANI


People also ask

Which directory contains a file in Linux?

Most global config files are located in the /etc directory. The /etc/ directory feels more like a filesystem and has many sub-directories, each having related config files.

How do I get a list of folders and subfolders with the files in Linux?

The ls command is used to list files or directories in Linux and other Unix-based operating systems. Just like you navigate in your File explorer or Finder with a GUI, the ls command allows you to list all files or directories in the current directory by default, and further interact with them via the command line.


1 Answers

You could use find like this:

find -type d -exec sh -c '[ -f "$0"/index.php ] && [ -f "$0"/style.css ]' '{}' \; -print

To search for more files, simply add them like && [ -f "$0"/other_file ]. The return code of sh will indicate whether all the files could be found. The name of the directory will only be printed if sh has exited successfully, i.e. when all the files have been found.

Testing it out:

$ mkdir dir1
$ touch dir1/a
$ mkdir dir2
$ touch dir2/a
$ touch dir2/b
$ find -type d -exec sh -c '[ -f "$0"/a ] && [ -f "$0"/b ]' '{}' \; -print
./dir2

Here I've created two directories, dir1 and dir2. dir2 contains both files, so its name is printed.

As gniourf_gniourf has mentioned in the comments (thanks), it is not necessary to use sh to do this. Instead, you can do this:

find -type d -exec test -f '{}'/a -a -f '{}'/b \; -print

[ and test do the same thing. This approach uses -a instead of && to combine multiple separate tests, which reduces the number of processes being executed.

In response to your comment, you can add all of the directories found to an archive like this:

find -type d -exec test -f '{}'/a -a -f '{}'/b \; -print0 | tar --null -T - -cf archive.tar.bz2

The -print0 option prints the names of each of the directories, separated by a null byte. This is useful as it prevents problems with files containing spaces in their names. The names are read by tar and added to the bzip-compressed archive. Note that some versions of find do not support the -print0 option. If your version doesn't support it, you may be able to use -print (and remove the --null option to tar), depending on your directory names.

like image 151
Tom Fenech Avatar answered Oct 18 '22 07:10

Tom Fenech