Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I want to run a command to:

  1. Find all directories named "inc" under a folder "X".
  2. List all the subdirectories under each "X/.../inc/".
  3. Redirect the output to a file named "list"

I tried various combinations of the below command, without success:

$ find X/ -name "inc" -print | xargs find {} -type d > list
find: path must precede expression

How can I do this?

share|improve this question
add comment

4 Answers

up vote 3 down vote accepted

find can do this all by itself:

find X -path '*/inc/*' -type d > list

Read the -path part of man find for more info.

As I mentioned quickly in a comment: if you store the directories line separated in a text file, directory names containing newlines won't be unambiguously representable. If you are certain that directories don't contain newlines, that's OK. Just a general remark.

share|improve this answer
    
You always learn something new, nice! –  slhck May 18 '12 at 14:39
    
yea. i gave the same answer here –  Prince John Wesley May 18 '12 at 15:02
    
Or find X -name 'inc' -type d > list –  MaQleod May 18 '12 at 15:06
    
@MaQleod: No, that is not the question. –  Daniel Andersson May 18 '12 at 15:11
add comment

Here's a handy one-liner:

find X -type d -name "inc" -exec sh -c 'find {} -type d' \; > list

It runs find on each of the first find results. The exec option can also take a minimal shell command, in which – as I said – {} is replaced with each directory of the first find.

The second find will, per your request, "list all subdirectories" of the first results, including the inc directory. If you don't want that itself in the output, let the second find at least output folders of depth 1.

find X -type d -name "inc" -exec sh -c 'find {} -mindepth 1 -type d' \; > list

We'll then just redirect the command's stdout into list.

share|improve this answer
add comment

Alright I have found the answer to simulate this nested find:

find X/ -type d | grep "/inc/" > list
share|improve this answer
    
Nice, that'll work, too! However, in Unix/Linux shells, there's really no such thing as the answer. It's a mixture of personal preferences and what's easy to follow. –  Vishal Kotcherlakota May 18 '12 at 6:47
    
To take care of unconventional (but existing) file names with e.g. newlines: find X/ -type d -print0 | awk 'BEGIN{RS="\0"}/\/inc\//' > list (grep -z also delimits on the null character, but its output seems to be null separated as well, so then one would need to pipe it through e.g. xargs -0L1 echo to get it line by line). In this case, since you are saving the list to file with every entry separated by newline, newlines in file names will still be ambiguously represented. Perhaps you do not even need the intermediate file, depending on what you want to do with the list. –  Daniel Andersson May 18 '12 at 10:55
add comment

Try this:

   find path-of-x -path '*/inc/*' -type d > list
share|improve this answer
    
i don't have linux machine to test it now... –  Prince John Wesley May 18 '12 at 6:36
    
This doesn't work. But thanks for suggesting me "\inc\" :) –  iammilind May 18 '12 at 6:40
    
@iammilind: try with -path flag –  Prince John Wesley May 18 '12 at 6:50
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.