linux - Using Unix's find command to find directories matching name but not subdirectories with same name
2014-07
Edited: I mistakenly misrepresented my problem. A more accurate example now appears below.
I'd like to recursively walk all directories inside a target directory, and stop each recursive call after the first .git directory is found.
For example, if we have these paths:
/home/code/twitter/.git/
/home/code/twitter/some_file
/home/code/twitter/some_other_file
/home/code/facebook/.git/
/home/code/facebook/another_file
/home/code/configs/.git/
/home/code/configs/some_module/.git/
/home/code/configs/another_module/.git/
/home/code/some/unknown/depth/until/this/git/dir/.git/
/home/code/some/unknown/depth/until/this/git/dir/some_file
I want only these lines in the result:
/home/code/twitter
/home/code/facebook
/home/code/configs
/home/code/some/unknown/depth/until/this/git/dir/
The -maxdepth
won't help me here because I don't know how deep the first .git dir will be for each subdirectory of my target.
I thought find /home/code -type d -name .git -prune
would do it, but it's not working for me. What am I missing?
Sounds like you want the -maxdepth
option.
find /home/code -maxdepth 2 -type d -name .git
It's tricky and -maxdepth and recursion trickery won't help here, but here's what I would do:
find /home/code -type d -name ".git" | grep -v '\.git/'
In english: find me all directories named ".git" and filter out any occurences in the resultlist which contain ".git/" (dot git slash).
Above commandline will work on all unix systems, however, if you can assert that your find will be "GNU find", then this will also work:
find /home/code -type d -name ".git" ! -path "*/.git/*"
Have fun.
Find all directories which contain a .git subdirectory:
find /home/code -type d -name .git -exec dirname {} \;
Performing a search from the current directory where this file resides, this find command finds the file.
# find . page.tpl.php
However, when I search from a child directory, this command,
# find ../. page.tpl.php
prints out the list of files, WITH the requested file listed in the output,
.././parent_dir/page.tpl.php
However, the results are,
find: `page.tpl.php': No such file or directory
Then when I add the -name argument it works,
# find ../. -name page.tpl.php
I simply forget to use arguments sometimes and the false negative is really aggravating. What's going on?
find [path] [expressions]
A filename isn't an expression.
The default action is to print.
For path, ".." is better than "../." you almost never need to include "." unless it's at the start of a relative path.
The command find uses:
find [-H] [-L] [-P] [path...] [expression]
Your first example was:
find ../. page.tpl.php
What you did was give find two search paths. As the default expression is print, the contents of the two paths were printed to stdout.
Consider this:
mkdir a b c
touch a/file1 a/file2 b/SANTACLAUS c/MONKEYS
find a b
$ find a b
a
a/file2
a/file1
b
b/SANTACLAUS
Your second example was:
.././parent_dir/page.tpl.php
Here you provided one search path. The error tells you that page.tpl.php wasn't found in CWD. I assume this was due to your not having the file 'page.tpl.php' under the directory 'parent_dir'.