Find command ignore directory - linux

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

Related

Using find to find files WITH a certain pattern and not other pattern

I want to use find to find files with _101_ in the name and not .jpg or .wsq extensions, but I cannot get this to work.
I tried things like this:
find . -type f -name '*_101_*' -o -not -name *.jpg -o -name *.wsq
but it doesn't work.
What am I doing wrong?
Your attempt does "matches _101_, or does not end in .jpg, or does not end in .wsq". That'll match every single file, based on the two extensions alone, as a file can only have one.
You have to group differently:
find . -type f -name '*_101_*' -not -name '*.jpg' -not -name '*.wsq'
This applies all rules (logical AND is implied).
You also should quote the parameters to -name, or they might be expanded by the shell instead of find.
You need to use parenthesis (or #Benjamin's solution)
otherwise a or not b or c is evaluated as (a or not b) or c.
And you need and instead of or to filter only files that satisfy both conditions (pass both tests). a and not (b or c)
find -name '*_101_*' -not \( -name '*.jpg' -o -name '*.wsq' \)

Find all files contained into directory named

I would like to recursively find all files contained into a directory that has name “name1” or name “name2”
for instance:
structure/of/dir/name1/file1.a
structure/of/dir/name1/file2.b
structure/of/dir/name1/file3.c
structure/of/dir/name1/subfolder/file1s.a
structure/of/dir/name1/subfolder/file2s.b
structure/of/dir/name2/file1.a
structure/of/dir/name2/file2.b
structure/of/dir/name2/file3.c
structure/of/dir/name2/subfolder/file1s.a
structure/of/dir/name2/subfolder/file2s.b
structure/of/dir/name3/name1.a ←this should not show up in the result
structure/of/dir/name3/name2.a ←this should not show up in the result
so when I start my magic command the expected output should be this and only this:
structure/of/dir/name1/file1.a
structure/of/dir/name1/file2.b
structure/of/dir/name1/file3.c
structure/of/dir/name2/file1.a
structure/of/dir/name2/file2.b
structure/of/dir/name2/file3.c
I scripted something but it does not work because it search within the files and not only folder names:
for entry in $(find $SEARCH_DIR -type f | grep 'name1\|name2');
do
echo "FileName: $(basename $entry)"
done
If you can use the -regex option, avoiding subfolders with [^/]:
~$ find . -type f -regex ".*name1/[^/]*" -o -regex ".*name2/[^/]*"
./structure/of/dir/name2/file1.a
./structure/of/dir/name2/file3.c
./structure/of/dir/name2/subfolder
./structure/of/dir/name2/file2.b
./structure/of/dir/name1/file1.a
./structure/of/dir/name1/file3.c
./structure/of/dir/name1/file2.b
I'd use -path and -prune for this, since it's standard (unlike -regex which is GNU specific).
find . \( -path "*/name1/*" -o -path "*/name2/*" \) -prune -type f -print
But more importantly, never do for file in $(find...). Use finds -exec or a while read loop instead, depending on what you really need to with the matching files. See UsingFind and BashFAQ 20 for more on how to handle find safely.

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.

Alternative way to find all files in a folder and subfolders

Is there any alternative for below command to find files in a folder and subfolders as well.
find . | egrep '\./[^/]+/[^/]+/[^/]+'
Note: I don't want directories I want to get only files
Additionally, you could specify list of files extensions as your search options:
find . -type f -name "*.js" -o -name "*.ros" -o -name "*.php"
Above example, would only display file names with *.ros, *.php, and *.js as file extensions under specific folder and subfolders.
Why don't you just use find?
I am not sure from your question if you want to limit the depth. If so:
find . -type f -depth 2 -print
If you just want to find files
find . -type f -print
If you just want to find directories
find . -type d -print
You can also use -ls if -print does not float your boat.
find . -type f -ls

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/##"

Resources