48

I am trying to list all the files from dir1, dir2, dir3 and dir4 which might be anywhere in as a sub directory of my cwd using the find command. I tried the following with no success:

find . -type f -regextype posix-egrep -regex 'dir1/.+|dir2/.+|dir3/.+|dir4/.+'

I tried posix-extended as well. How can I list these files?

| improve this question | | | | |
65

And if you want to search three folders named foo, bar, and baz for all *.py files, use this command:

find foo bar baz -name "*.py"

so if you want to display files from dir1 dir2 dir3 use find dir1 dir2 dir3 -type f

try this find . \( -name "dir1" -o -name "dir2" \) -exec ls '{}' \;

| improve this answer | | | | |
  • I should have clarified. I might not have the path to the files I wish to search. I only know they are sub directories of the current dir. – Aaron Jan 10 '13 at 6:21
  • use ./dir instead of dir – harish.venkat Jan 10 '13 at 6:24
  • The dir would still need to be in the cwd though, it may be two levels lower (e.g. ./path/to/dir1), in which case ./dir1 would not exist. – Aaron Jan 10 '13 at 6:28
  • edited the answer. – harish.venkat Jan 10 '13 at 6:46
11

It's best to use the -path directive:

find .  \( -type f -and -path '*/dir1/*' -or -path '*/dir2/*' -or -path '*/dir3/*' -or -path '*/dir4/*' \)

Which means: find all files under current directory where there's 'dir1' or 'dir2' or 'dir3' or 'dir4' in the path.

| improve this answer | | | | |
  • You've got the parenthesis in the wrong place. See also -a and -o for the standard equivalent of GNU's -and/-or. – Stéphane Chazelas Sep 4 '17 at 20:22
4

Just to let everyone know. Adding .*/ before each dir solved the problem since the regex is matching against the full path it seems.

| improve this answer | | | | |
3

This is my first idea after reading the previous answers:

find . -type f -regextype posix-egrep -regex ".*/(dir1|dir2|dir3|dir4)/.+"

This takes into account, that the regex must match the whole filename, and it is easier to understand.

| improve this answer | | | | |
2

Sample of fast(!) finding particular files (access_log) in multiple locations defined by wildcard (home directory) and general apache2 log directory applying also name filtering to exclude ssl logs and gzipped old logs. Does not directly answer the question here but might be userful for someone who found these instructions (like me).

find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*"

Be careful with spaces, specially near to \( and \).

By the way, I used it for apachetop, to find most active websites in my server.

apachetop -d1 -s9 -p $(find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*" -print | sed 's/^/-f '/)
| improve this answer | | | | |
2

you dont need to specify dir1 to dir4 by name if you are using regextype

find . -type f -regextype sed -regex ".*/dir[1-4]/[^/]*"
  • type f: find files not directories
  • regextype sed: uses sed regextype
  • regex: searches using regex in the entire path
  • ".*/dir[1-4]/[a-z0-9]*": .* at the beginning means any number of characters which could be of type (char/number/backslash(/) etc); dir[1-4] means look for "dir" followed by a number between 1 and 4; /[^/]* states that following dir1-4 omit any pathnames which have / in them, so it only returns files in the directory dir1-dir4 and ignores any subdirectories that may be within dir1-dir4.

created a directory for you to test it out: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution04092017

| improve this answer | | | | |
  • (1) We may never know Aaron's exact situation or requirements, but other answers have made the prudent decision that he has four directories, whose names are unspecified.   (They could be red, green, blue and yellow, or they could be John, Paul, George and Ringo.)   Your answer assumes that they are literally dir1, dir2, dir3 and dir4. … (Cont’d) – Scott Sep 4 '17 at 20:32
  • (Cont’d) …  (2) Why do you assume that Aaron doesn’t want to search subdirectories?  He seems to be saying that he does.  (3) Why are you restricting the search to files whose names contain only lower-case letters and digits (excluding things like foo_bar, foo.txt and FOO)?  (4) Why does your text explain /[^/]* when your answer doesn’t use it? – Scott Sep 4 '17 at 20:32
  • Hi Scott, thats for your comment. – alpha_989 Sep 4 '17 at 21:12
  • (1-3). he mentions "I am trying to list all the files from dir1, dir2, dir3 and dir4" which might be anywhere in as a sub directory of my cwd, which means that dir1-dir4 might be anywhere, but he wants to find file right within dir1-dir4. ofcourse, if its not dir1-dir4, you have to change it to the specific names using red\|blue\|green\| etc.. – alpha_989 Sep 4 '17 at 21:12
  • 4. typo there.. I used [a-z0-9]* before..then realized [^/]* is shorter and more inclusive..forgot to change it when I posted this. Thanks for your careful comments. – alpha_989 Sep 4 '17 at 21:15
0

I know you specified that using find, but only to show other options that can be used, you can use xargs:

find . -type d | grep -E "dir1$|dir2$" | xargs ls  

find . -name "dir1" -or -name "dir2" | xargs ls

You can have a file named "folders" that contains something like:

$ cat folders
dir1
dir2
dir3
dir4

Then, you can do something like this:

$ cat folders | xargs -I % find . -type d -name % | xargs ls
./Documents/dir1:
file1  file2  file3  file4

./Documents/dir2:
file1  file2  file3  file4

./Documents/dir3:
file1  file2  file3  file4

./Documents/dir4:
file1  file2  file3  file4

xargs in my opinion, I feel more versatile than find -exec. Also you can make some crazy stuff like

$ cat << EOF | xargs -I {} find ~ -name "{}" | xargs ls
> dir1
> dir2
> dir3
> EOF
/home/user/Documents/dir1:
file1  file2  file3  file4

/home/user/Documents/dir2:
file1  file2  file3  file4

/home/user/Documents/dir3:
file1  file2  file3  file4
| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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