Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
find */ -iname '*.jpg' -type f -mtime +14 -exec ls -l {} \;
Not this
Code:
find */*.jpg -type f -mtime +14 -exec ls -l {} \;
Which will fix your original issue as well
Code:
-name pattern
Base of file name (the path with the leading directories
removed) matches shell pattern pattern. Because the leading
directories are removed, the file names considered for a match
with -name will never include a slash, so `-name a/b' will never
match anything (you probably need to use -path instead). A
warning is issued if you try to do this, unless the environment
variable POSIXLY_CORRECT is set. The metacharacters (`*', `?',
and `[]') match a `.' at the start of the base name (this is a
change in findutils-4.2.2; see section STANDARDS CONFORMANCE
below). To ignore a directory and the files under it, use
-prune; see an example in the description of -path. Braces are
not recognised as being special, despite the fact that some
shells including Bash imbue braces with a special meaning in
shell patterns. The filename matching is performed with the use
of the fnmatch(3) library function. Don't forget to enclose
the pattern in quotes in order to protect it from expansion by
the shell.
-iname pattern
Like -name, but the match is case insensitive. For example, the
patterns `fo*' and `F??' match the file names `Foo', `FOO',
`foo', `fOo', etc. The pattern `*foo*` will also match a file
called '.foobar'.
Giving find a glob as a directory name is more than a bit iffy. There are valid ways to do that, but I recommend against it.
Just off the top I might do something like this
Code:
for foo in 20* ; do
if [ -d ${foo} ] ; then
find ${foo} -type f -mtime +14 -ls
fi
done
to list them all, and
Code:
for foo in 20* ; do
if [ -d ${foo} ] ; then
find ${foo} -type f -mtime +14 -ls -delete
fi
done
to list and delete them in one step, or
Code:
for foo in 20* ; do
if [ -d ${foo} ] ; then
find ${foo} -type f -mtime +14 -delete
fi
done
to just delete them silently.
This assumes the behavior of the GNU version of find.
Giving find a glob as a directory name is more than a bit iffy. There are valid ways to do that, but I recommend against it.
Just off the top I might do something like this
Code:
for foo in 20* ; do
if [ -d ${foo} ] ; then
find ${foo} -type f -mtime +14 -ls
fi
done
I see the test for a directory, but why is for foo in 20* better then find 20*/?
Quote:
This works
find */ -iname '*.jpg' -type f -mtime +14 -exec ls -l {} \;
Thanks Sefyir
Take some time to examine why it works, and why yours failed. Otherwise you will run into this issue again.
I see the test for a directory, but why is for foo in 20* better then find 20*/?
When you use a glob for the path, you need to ensure you do it in a way that the shell will expand into something acceptable to find as a list of paths. To address this you can just go blind in the command, but know your directory well enough to be quite sure, or you can limit and test in the way you glob, or you can loop as did I and only give find a single verified path per invocation.
As you see above, mine is only ONE solution, and clearly not the most concise. There is always more than one right way. How you THINK is more interesting than the problem itself. The most natural thing for me is the 'divide and conquer' approach. Adjusting your command line to an invoke less likely to be fooled by unexpected glob expansion is another. They are all valid, and all work to accomplish your goal.
PS. The original posts crossed. When I gave my first response, it appeared the ONLY response. I was not responding to any of the other replies, because I had not seen them. I would not have you think that one solution is 'better' than the others, all of them that WORK are 'good' answers.
tells find to search the entire system. including anything that is plugged into it, ie USB, if it is mounted then it will be searched. the only thing that will prevent a directory from being search using that is permissions.
in other words if you type
Code:
find / -name *jpg
it will spit out everything thing that it matches except it will not search areas it does not have permissions to do so.
output
PS. The original posts crossed. When I gave my first response, it appeared the ONLY response. I was not responding to any of the other replies, because I had not seen them. I would not have you think that one solution is 'better' than the others, all of them that WORK are 'good' answers.
Ah my mistake!
Yes, there are many ways to solve it.
Quote:
Originally Posted by BW-userx
in other words if you type
Code:
Code:
find / -name *jpg
it will spit out everything thing that it matches except it will not search areas it does not have permissions to do so.
output
You are correct, however be aware if there are any *jpg files in the directory where you run the command, the shell will expand *jpg to those files. It will also not match foo.JPG because -name is case-sensitive (use -iname to get past this one)
Eg. if you run it in a directory that contain foo.jpg, the shell will replace
Ah my mistake!
Yes, there are many ways to solve it.
You are correct, however be aware if there are any *jpg files in the directory where you run the command, the shell will expand *jpg to those files. It will also not match foo.JPG because -name is case-sensitive (use -iname to get past this one)
Eg. if you run it in a directory that contain foo.jpg, the shell will replace
Code:
find / -name *jpg
-> find / -name foo.jpg
The correct manner is to either escape it or quote it.
Code:
find / -name "*jpg"
find / -name \*jpg
or you can just drop that completely then look at what you get using just this.
Code:
find / *jpg
Code:
userx@Voided.1 & ~ >> $find / \*jpg | wc -l
find: ‘*jpg’: No such file or directory
1497073
@BW-userx, the glob is to be done by the find command, not by the shell. Therefore must be escaped, e.g. with quotes
Code:
find / -name "*jpg"
--
The */ glob lists only directories. Should work with all shells, and is perfectly valid.
The only side effect is it remains */ if there is no directory (unless nullglob option is set), but this will give a clear error message in find, not any unwanted action.
@BW-userx, the glob is to be done by the find command, not by the shell. Therefore must be escaped, e.g. with quotes
Code:
find / -name "*jpg"
--
The */ glob lists only directories. Should work with all shells, and is perfectly valid.
The only side effect is it remains */ if there is no directory (unless nullglob option is set), but this will give a clear error message in find, not any unwanted action.
hum never seen it done like that but thanks good info to know.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.