最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

bash find directoryfile in undetermined number of levels - Stack Overflow

programmeradmin1浏览0评论

In bash, I am trying to find directories containing a specific file; however, these directories are on different levels, eg, if I am looking for dir03/myfile.txt:

dir01/dir02/dir03/myfile.txt
dir01/dir03/ ##no target file in it
dir01/dir04/dir05/dir03/myfile.txt
dir01/dir04/dir05/dir06/myfile.txt ##I do not want this

I could do:

find ./dir01 -type -d -iname "dir03"

But then I would get all directories, even the ones without the target file

If I do this:

find ./dir01/*/dir03 -iname "myfile.txt" 

I would not see "dir01/dir04/dir05/dir03/myfile.txt"

This does not work:

find ./dir01 -iname "dir03/myfile.txt"

##find: warning: Unix filenames usually don't contain slashes (though pathnames do).  
That means that '-iname ‘dir03/myfile.txt’' will probably evaluate to false all the time on this system.  You might find the '-wholename' test more useful, or perhaps '-samefile'.  Alternatively, if you are using GNU grep, you could use 'find ... -print0 | grep -FzZ ‘dir03/myfile.txt’'

I can do this:

find ./dir01 -iname "myfile.txt" -print0 | grep -FzZ 'dir03' | sed "s/myfile\.txt/\n/g"

It finds all the matches where myfile.txt is, and gets only the ones contained by the target directory; after that, I split the results with a new line (the line above gives the results concatenated, eg ./dir01/dir02/dir03/myfile.txt./dir01/dir04/dir05/dir03/myfile.txt But it might make the search more generic and longer in case I have a complex subdirectory structure. I was wondering if there was an easier solution to tell find to find "dir03/myfile.txt" at any level

Please note that the directory names are just for example sake, they do not share the same prefix.

Edit: I guess I could do

find ./dir01 -iname "myfile.txt" > myres0.txt
grep 'dir03' myres0.txt > myres1.txt

Considering that I am looking for multiple parental directories and not just dir03, it would do just one search, then I can use a txt file with my target directories and do:

grep -f mytargetDirs.txt myres0.txt > myres1.txt

Still wondering if there is a better way though.

In bash, I am trying to find directories containing a specific file; however, these directories are on different levels, eg, if I am looking for dir03/myfile.txt:

dir01/dir02/dir03/myfile.txt
dir01/dir03/ ##no target file in it
dir01/dir04/dir05/dir03/myfile.txt
dir01/dir04/dir05/dir06/myfile.txt ##I do not want this

I could do:

find ./dir01 -type -d -iname "dir03"

But then I would get all directories, even the ones without the target file

If I do this:

find ./dir01/*/dir03 -iname "myfile.txt" 

I would not see "dir01/dir04/dir05/dir03/myfile.txt"

This does not work:

find ./dir01 -iname "dir03/myfile.txt"

##find: warning: Unix filenames usually don't contain slashes (though pathnames do).  
That means that '-iname ‘dir03/myfile.txt’' will probably evaluate to false all the time on this system.  You might find the '-wholename' test more useful, or perhaps '-samefile'.  Alternatively, if you are using GNU grep, you could use 'find ... -print0 | grep -FzZ ‘dir03/myfile.txt’'

I can do this:

find ./dir01 -iname "myfile.txt" -print0 | grep -FzZ 'dir03' | sed "s/myfile\.txt/\n/g"

It finds all the matches where myfile.txt is, and gets only the ones contained by the target directory; after that, I split the results with a new line (the line above gives the results concatenated, eg ./dir01/dir02/dir03/myfile.txt./dir01/dir04/dir05/dir03/myfile.txt But it might make the search more generic and longer in case I have a complex subdirectory structure. I was wondering if there was an easier solution to tell find to find "dir03/myfile.txt" at any level

Please note that the directory names are just for example sake, they do not share the same prefix.

Edit: I guess I could do

find ./dir01 -iname "myfile.txt" > myres0.txt
grep 'dir03' myres0.txt > myres1.txt

Considering that I am looking for multiple parental directories and not just dir03, it would do just one search, then I can use a txt file with my target directories and do:

grep -f mytargetDirs.txt myres0.txt > myres1.txt

Still wondering if there is a better way though.

Share Improve this question edited Mar 3 at 17:43 Max_IT asked Mar 3 at 17:38 Max_ITMax_IT 6385 silver badges18 bronze badges 2
  • 2 You might want to check find -path – bfontaine Commented Mar 3 at 17:47
  • 2 Questions about using Unix commands belong on Unix & Linux. SO is for programming questions. – Barmar Commented Mar 3 at 17:57
Add a comment  | 

3 Answers 3

Reset to default 5
$ find dir01 -type f -path "*/dir03/myfile.txt"
dir01/dir02/dir03/myfile.txt
dir01/dir04/dir05/dir03/myfile.txt

You probably don't need -type f but it felt instinctual for me to include it

With bash and its enabled globstar:

shopt -s globstar; printf "%s\n" **/dir03/myfile.txt

Output:

dir01/dir02/dir03/myfile.txt
dir01/dir04/dir05/dir03/myfile.txt

Sounds like this is all you need:

find ./dir01 -type f -name 'myfile.txt' | grep '/dir03/[^/]*$'

Add NUL-termination options (-print0 and grep -Z) to protect against newlines in directory/file names as you see fit.

发布评论

评论列表(0)

  1. 暂无评论