Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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
add comment

4 Answers

up vote 4 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
add comment

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-                       |
rev

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. –  Stephane Chazelas Jan 29 at 13:13
add comment

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

or

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 at 11:18
add comment
find . -name "__openerp__.py" -exec sh -c '(cd "{}"/../../; pwd)' \; | uniq
share|improve this answer
1  
Never include {} in the sh code. –  Stephane Chazelas Jan 29 at 13:06
    
@StephaneChazelas why? –  JackLeo Jan 29 at 13:12
3  
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. –  Stephane Chazelas Jan 29 at 13:15
add comment

Your Answer

 
discard

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.