Find leaf directories contained within directories matching a wildcard - linux

The following works very well. It gets me leaf directories.
find . -type d -links 2
What I need is something like below. In the current directory, there are directories named as C2S7*, within those I need the leaf directories.
find . -name "C2S7*" -type d -links 2
The above looks for the wildcard in the leaf directory names as well. What is the alternative?

To look inside direct children matching the pattern:
find C2S7*/ -type d -links 2
To look inside direct or indirect children matching the pattern:
find . -path "*/C2S7*/*" -type d -links 2
Specification.

Related

How to list non-empty directories with the command find or ls?

It is necessary to list non-empty directories in a subdirectory
Trying to use
find . ! -type d -empty -print
but it doesn't work,
You're asking for "things that are not directories and are empty", which includes all zero-length files (and would exclude all directories). You want "things that are directories and are not empty", so:
find . -type d ! -empty -print

Shell script to list all subdirectories recursively within a folder that contains files with an specific extension

I have a folder named a, and it may have one or multiple sub-directories and the sub-directories may have multiple sub-directories and so on. I want to know how can I write a shell script to list all the sub-directories that contain a file with specific extension.
So, it may be like
A -> B -> C
-> D -> f2.txt
-> F -> f3.txt
-> E -> G -> H -> f4.txt
So only D, F and H directories will be listed. Actually I need this as a quick way to find the package names of particular java classes, by listing their directory tree. For example in the previous example A.E.G.H is a package same as A.D, but A.E.G is not a package as G only contains a sub directory H no files.
I think you need find command. You can use like this,
find . -name '*.txt'
Here,
. - dot(.) is current directory. You can also specify the path where to start.
-name - file name to find.
You can also use -maxdepth option to limit the depth of recursive finding. Normally, find will find the file recursively.
Update:
If you want to list out the directories,
find . -name '*.txt' -exec dirname {} \;
find . -name '*.txt' -printf '%h\n'
man find will give other possible format flags usable with -printf
A simpler and faster alternative for systems like MAC. No need to use 2 additional tools and even repeatingly call dirname:
find -type f -name '*.txt' | awk 'BEGIN{FS=OFS="/"}{--NF}!a[$0]++'
-type f may be removed optionally if it doesn't work.

Find command ignore directory

I am trying to find all files ending in .jar, but it is picking up folders that ends in .jar which is something I do not want.
My command so far
find . -name ".*jar"
I need it so it ignores directories ending in .jar
Additional request.
I now need to ignore a specific folder when looking, is this possible?
Thanks.
just add -type f:
find . -name "*.jar" -type f
Others have already shown, how to pick up files named ending in .jar. As an answer to your comment "How to ignore a specific folder". You use -prune for that
find . -name 'specific/folder' -type d -prune -o -type f -name '*.jar'
that's what you want
find . -type f -name "*.jar"
see man page:
-type Type
Evaluates to the value True if the Type variable specifies one of the following values:
b
Block special file
c
Character special file
d
Directory
f
Plain file
l
Symbolic link
p
FIFO (a named pipe)
s
Socket

how to exclude few folder levels in the FIND command results - unix

Following is the folder structure
- home/ABCD/test1/example1/sample1/textfile.txt
If I execute the find command like
find /home/ABCD/ -type f -print
I am getting the following output
/home/ABCD/test1/example1/sample1/textfile.txt
Note: I am executing the find command from the ABCD folder, In the results I want to exclude /home/ABCD/ folder I just want /test1/example1/sample1/testfile.txt as the result
How can I achieve this?
Since you are executing find from /home/ABCD/ do something like this:
find * -type f -print
Or if you are looking for files in test1 do this:
find test1 -type f -print
Also with -maxdepth N you can limit the recursion in find
If you only want to look for files named textfile.txt do
find test1 -type f -name 'textfile.txt' -print
If you want to print the leading slash do
find . -type f -printf '/%p\n'
For more info have a look here
Note: If have the above string in a variable, you can trim it like this:
string="/home/ABCD/test1/example1/sample1/textfile.txt"
echo "${string#/home/ABCD}"
Some more examples of string manipulation here
Just use . as the starting directory
find . -type f -print
gives
./test1/example1/sample1/textfile.txt
and if you really want a leading slash, use -printf for the output
find . -type f -printf '/%P\n'
You can use the mindepth parameter to start looking at one level below the current directory
find /home/ABCD/ -mindepth 1 -type f -print
This should substitute your current working directory name with a .
find . -type f | perl -pne "s#$PWD#.#"
So you would get results like:
./test1/example1/sample1/textfile.txt
If you do not want the preceeding ./, use this command instead:
find . -type f | perl -pne "s#$PWD/##"

Find Directories With No Files in Unix/Linux

I have a list of directories
/home
/dir1
/dir2
...
/dir100
Some of them have no files in it. How can I use Unix find to do it?
I tried
find . -name "*" -type d -size 0
Doesn't seem to work.
Does your find have predicate -empty?
You should be able to use find . -type d -empty
If you're a zsh user, you can always do this. If you're not, maybe this will convince you:
echo **/*(/^F)
**/* will expand to every child node of the present working directory and the () is a glob qualifier. / restricts matches to directories, and F restricts matches to non-empty ones. Negating it with ^ gives us all empty directories. See the zshexpn man page for more details.
-empty reports empty leaf dirs.
If you want to find empty trees then have a look at:
http://code.google.com/p/fslint/source/browse/trunk/fslint/finded
Note that script can't be used without the other support scripts,
but you might want to install fslint and use it directly?
You can also use:
find . -type d -links 2
. and .. both count as a link, as do files.
The answer of Pimin Konstantin Kefalou prints folders with only 2 links and other files (d, f, ...).
The easiest way I have found is:
for directory in $(find . -type d); do
if [ -n "$(find $directory -maxdepth 1 -type f)" ]; then echo "$directory"
fi
done
If you have name with spaces use quotes in "$directory".
You can replace . by your reference folder.
I haven't been able to do it with one find instruction.

Resources