I’m trying to use the find command in bash. Finding the file by matching part of the name of a file and the age of the file like so:
find . -name “*sample*” -type f -print -mtime +5
Which will print all the files in the current directory containing the name sample. What I want is however is to only print those older than 5 days and it doesn’t matter what number I set the -mtime parameter to it always prints out all the files containing sample regardless.
Any ideas?
find expects arguments grouped together - Tests (name, mtime, type etc) must come before Action (print, exec etc).
The following should work:
find . -name “*sample*” -type f -mtime +5 -print
Related
I have files with name as
filename_201702200800.tar.bz2
filename_201702201800.tar.bz2
and so on
I am looking to remove files which are 5 days and older.
The date in the files is of the format %Y%m%d%H%M.
As the creation time corresponds to the names, just use find:
find /path/to/files -type f -ctime +5 -exec rm {} +
From man page:
-exec command {} +
This variant of the -exec action runs the specified command on the selected files, but the command line is built by
appending each selected file name at the end; the total number of
invocations of the command will be much less than the number of
matched files. The command line is built in much the same way that
xargs builds its command lines. Only one instance of ‘{}’ is
allowed within the command. The command is executed in the starting
directory.
Not enough rep to comment.
Can you use the mtime of the files?
find /path/to/files -type f -mtime +5 -delete
Otherwise, you could calculate the dates to find with:
date -d "5 days ago" +%Y%m%d%H%M
I am aware of this related question.
What I want is just the date and time of the last modification for any file inside a directory (recursively, the whole tree). Is there any fast way to do this for large directories?
Alternatively, I could also use a check telling me whether there was any modification after a given date.
To list the timestamp of all files in the folder :
find . -type f -printf '%t\n'
To get a unix timestamp :
find . -type f -printf '%T#\n'
To list the timestamp of all files that were modified within the last 5 days
find . -type f -mtime -5 -printf '%t\n'
Note : all those commands are recursives
I have a directory which contains a number of files (no subdirectories). I wish to find these files. The following gets me close:
$ find docs
docs
docs/bar.txt
docs/baz.txt
docs/foo.txt
I don't want the directory itself to be listed. I could do this instead:
$ find docs -type f
docs/bar.txt
docs/baz.txt
docs/foo.txt
Using a wildcard seems to do the trick as well:
$ find docs/*
docs/bar.txt
docs/baz.txt
docs/foo.txt
My understanding is that these work in different ways: with -type, we're providing a single path to find, whereas in the latter case we're using wildcard expansion to pass several paths to find. Is there a reason to favour one approach over the other?
You have a UNIX tag, and you example has a *. Some versions of find have a problem with that.
If the directory has no subdirectories.
FYI.
Generally the first parms to find has to be a directory or a list of directories
find /dir1 /dir2 -print
Find is recursive - so it will follow each directory down listing every thing, symlinks, directories, pipes, and regular files. This can be confusing. -type delimits your search
find /dir1 /dir2 -type f -print
You can also have find do extra output example: have it rm files older than 30 days for example:
find /dir1 /dir2 -type f -mtime +30 -exec rm {} \;
Or give complete infomation
find /dir1 /dir2 -type f -mtime +30 -exec ls -l {} \;
find /dir1 /dir2 -type f -mtime +30 -ls # works on some systems
To answer your question: because find can be dangerous ALWAYS fully specify each directory , file type ,etc., when you are using a nasty command like rm. You might have forgotten your favorite directory is also in there. Or the one used to generate your paycheck. Using a wildcard is ok for just looking around.
Using *
find /path/to/files -type f -name 'foo*'
-- tics or quotes around strings with a star in them in some UNIX systems.
find docs -type f
will get you a listing of every non-directory file of every subdirectory of docs
find docs/*
will get you a listing of every file AND every subdirectory of docs
I've found the following line of code in a script. Could someone explain me what does this following line of code means?
Basically, the purpose of this line is find a set of files to archive. Since I am not familiar with bash scripts, it is difficult for me to understand this line of code.
_filelist=`cd ${_path}; find . -type f -mtime ${ARCHIVE_DELAY} -name "${_filename}" -not -name "${_ignore_filename}" -not -name "${_ignore_filename2}"`
Let's break it down:
cd ${_path} : changes to the directory stored in the ${_path} variable
find is used to find files based on the following criteria:
. : look in the current directory and recurse through all
sub-directories
-type f: look for regular files only (not directories)
-mtime ${ARCHIVE_DELAY} : look for files last modified
${ARCHIVE_DELAY}*24 hours ago
-name "${_filename}": look for files which have name matching ${_filename}
-not -name "${_ignore_filename}" : do not find files which have
name matching ${_ignore_filename}
-not -name "${_ignore_filename2}" : do not find files which have
name matching ${_ignore_filename2}
All the files found are stored in a variable called _filelist.
The backtick (`) symbol assigns to the variable the output of the command.
Your script is assigning to $_filelist what you get by:
Changing directory to $_path
Finding in the current directory (.) files (-type f) where
Name is $_filename (a pattern, I suppose)
Name is not $_ignore_filename or $_ignore_filename2
I think you could as well change that to find ${_path} ... without the cd, but please try it out.
_filelist=`somecode`
makes the variable _filelist contain the output of the command somecode.
Somecode, in this case, is mostly a find command, which searches recursively for files.
find . -type f -mtime ${ARCHIVE_DELAY} -name "${_filename}" -not -name "${_ignore_filename}" -not -name "${_ignore_filename2}"
find .
searches the current dir, but this was just before changed to be _path.
-type f
only searches in ordinary files (not dirs, sockets, ...)
-mtime
specifies the modification time of that files, to be the same as ${ARCHIVE_DELAY}
-name explains
itself, has to be "${_filename}"
-not name
explains itself too, I guess.
So the whole part sets the variable filelist to files, found by some criterias: name, age, and type.
I have a directory with roughly 100000 files in it, and I want to perform some function on all files beginning with a specified string, which may match tens of thousands of files.
I have tried
ls mystring*
but this returns with the bash error 'Too many arguments'. My next plan was to use
find ./mystring* -type f
but this has the same issue.
The code needs to look something like
for FILE in `find ./mystring* -type f`
do
#Some function on the file
done
Use find with a wildcard:
find . -name 'mystring*'
ls | grep "^abc"
will give you all files beginning (which is what the OP specifically required) with the substringabc.
It operates only on the current directory whereas find operates recursively into sub folders.
To use find for only files starting with your string try
find . -name 'abc'*
If you want to restrict your search only to files you should consider to use -type f in your search
try to use also -iname for case-insensitive search
Example:
find /path -iname 'yourstring*' -type f
You could also perform some operations on results without pipe sign or xargs
Example:
Search for files and show their size in MB
find /path -iname 'yourstring*' -type f -exec du -sm {} \;