Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

what I want to do is to find all files based on some search query and get parents parent directory (../..) full path.

For example find . -name "__openerp__.py" and then for each file execute something along the lines of (cd ../..; pwd). Then pipe everything to uniq.

share|improve this question
up vote 5 down vote accepted

Assuming none of the file names contain newline characters:

find "$PWD" -name __openerp__.py  | awk -F/ -vOFS=/ 'NF-=2' | sort -u
share|improve this answer

Putting aside that there would be issues with file names that contain newlines, there are a couple of efficiency improvements I can think of:

  1. Pass the $PWD directly to find, instead of determining it for each sub-shell. This will make find include the full path in its output.
  2. Cut parent directory names off with rev and cut.

So I would suggest the following to get a list of all directories containing the desired file:

find "$PWD" -name '__openerp__.py' |
rev                                | 
cut -d/ -f3-                       |

Note that find does not order its output, so it should be sorted before uniq'ing it. As sort already supports squeezing identical elements (-u switch), the original question can then be answered with:

find "$PWD" -name '__openerp__.py' |
rev                                | 
cut -d/ -f3-                       |
rev                                |
sort -u
share|improve this answer
+1 Good point about sort -u. I initially thought that all the duplicate entries would be adjacent, but there isn't any reason for it. – Stéphane Chazelas Jan 29 '14 at 13:13

If I understand correctly, you want the list of directories containing a subdirectory containing a file called __openerp__.py, without duplicates.

In zsh:

print -rl -- **/__openerp__.py(:h:h) | sort -u


a=(**/__openerp__.py(:h:h)); print -rl -- ${(u)a}
share|improve this answer
+1 for (:h:h) didn't knew this one in zsh globbing. – JackLeo Jan 30 '14 at 11:18
find . -name "__openerp__.py" -exec sh -c '(cd "{}"/../../; pwd)' \; | uniq
share|improve this answer
Never include {} in the sh code. – Stéphane Chazelas Jan 29 '14 at 13:06
@StephaneChazelas why? – JackLeo Jan 29 '14 at 13:12
Because it's interpreted as shell code, so if you have for instance a file called $(rm -f "$HOME"), it will have expensive consequences. Also it doesn't work at all in many find implementations. Use sh -c 'cd -P "$1/../.." && pwd' sh {} \; instead. – Stéphane Chazelas Jan 29 '14 at 13:15

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.