alternatives to long-running `find` command in unix - unix

I want to delete files that are older than 7 days, and I'm using this command to do so:
find /directory -mtime +7 -exec rm -f {} \;
It is working fine except it takes too long. Is there any other way to delete files older than 7 days, e.g. without using find?

Using "-exec rm" is known to slow things down. If your find has the -delete option, then try using it instead, like so:
find /directory -type f -mtime +7 -delete
If your find does not have the -delete option, then consider using GNU find (which might already be available on your system as gfind).
There are other possibilities, e.g. using xargs. For further discussion and some other options, see Deleting-Files.

Change the final ; for a plus sign +
$ find /directory -type f -mtime +7 -exec rm -f {} \+
or use xargs command:
$ find /directory -type f -mtime +7 | xargs rm
Both will be at least 3 times faster

Related

Searching for particular files in a directory non-recursively using find. AIX

I have a script which has the following command. I am trying to edit this in such a way that it only searches the files in the directory of the path without going in the subdirectories. That is not recursive search
find {Path} -name "cor*" -type f -exec ls -l {} \;
Example: The command should give cor123.log only and not cor456.log. Currently it gives both
<Path>
..cor123.log
<directory>
..cor456.log
I tried using -maxdepth but it's not supported in AIX. -prune and -depth didn't help either.
Will appreciate any help. Thanks
You can use
find . -name . -o -prune
to find files and directories non-recursively.
So in your case this one will work:
find . -name . -o -prune -name 'cor*' -type f -exec ls -l {} \;
Do you need find for selecting files only?
When you know that all files starting with cor are regula files, you can use
ls -l ${Path}/cor*
or
ls -l ${Path}/cor*.log
When you need the -type f, you can try to filter the results.
The filename can not have a /, so remove everything with an / after the Path.
We do not know the last char of ${Path}. It can be /, which will make the grep -Ev "${Path}/.*/" filter useless. After the Path at least one character is needed before looking for the next /.
find "${Path}" -name "cor*" -type f 2>/dev/null| grep -Ev "${Path}..*/" | xargs -ls
Late answer but may save some. In aix
find /some/directory/* -prune -type f -name *.log
For instance make your path have the last forward slash with a wildcard then -prune
/*
find /some/directory/* -prune -name "cor*" -type f -exec ls -l {} \
Tested.

How to move or copy files listed by 'find' command in unix?

I have a list of certain files that I see using the command below, but how can I copy those files listed into another folder, say ~/test?
find . -mtime 1 -exec du -hc {} +
Adding to Eric Jablow's answer, here is a possible solution (it worked for me - linux mint 14 /nadia)
find /path/to/search/ -type f -name "glob-to-find-files" | xargs cp -t /target/path/
You can refer to "How can I use xargs to copy files that have spaces and quotes in their names?" as well.
Actually, you can process the find command output in a copy command in two ways:
If the find command's output doesn't contain any space, i.e if the filename doesn't contain a space in it, then you can use:
Syntax:
find <Path> <Conditions> | xargs cp -t <copy file path>
Example:
find -mtime -1 -type f | xargs cp -t inner/
But our production data files might contain spaces, so most of time this command is effective:
Syntax:
find <path> <condition> -exec cp '{}' <copy path> \;
Example
find -mtime -1 -type f -exec cp '{}' inner/ \;
In the second example, the last part, the semi-colon is also considered as part of the find command, and should be escaped before pressing Enter. Otherwise you will get an error something like:
find: missing argument to `-exec'
find /PATH/TO/YOUR/FILES -name NAME.EXT -exec cp -rfp {} /DST_DIR \;
If you're using GNU find,
find . -mtime 1 -exec cp -t ~/test/ {} +
This works as well as piping the output into xargs while avoiding the pitfalls of doing so (it handles embedded spaces and newlines without having to use find ... -print0 | xargs -0 ...).
This is the best way for me:
cat filename.tsv |
while read FILENAME
do
sudo find /PATH_FROM/ -name "$FILENAME" -maxdepth 4 -exec cp '{}' /PATH_TO/ \; ;
done

Unix find and move command

I need a Unix command to find all the text files older than 3 days and move them to some other location in single command.
In that case you want find and use its -exec and -mtime flags.
It should be something like:
find . -mtime -3 -type f -print0 | xargs -0 -I file mv file /new/dir/.
man find
man xargs

find command not working from other directory

My dir sturcture that looks like
x
/log
/bin
I am giving this command from dir- x/bin
find ../log -type f -name \*.log -mtime +90 -exec ls -l {} \;
(to find and display list of files older than 90 days.) and it doesn't display anything.
Whereas if i execute same command in dir- x/log
find . -type f -name \*.log -mtime +90 -exec ls -l {} \;
it gives me a list of files older than 90 days.
Can you please help?
Recall that paths are relative.
If you have a dir sturcture that looks like
x
/log
/bin
AND your're in x/bin then you need to give the relative path to x/log, ie
pwd
x/bin
find ../x/log -type f -name \*.log -mtime +90 -exec ls -l {} \;
I hope this helps.
Two suggestions.
First, escape the * using \*. If you have any log files in current dir, they will get expanded before the command is executed.
Second, I think you mean find ../x/log ...?

How to purge old directories programmatically in unix/shell?

Does anyone have a good shell line for this?
I want to check the age on a directory. If I created multiple directories on a weekly basis and I want to purge them/delete them based on 7 days later for example.
How would I do that?
This will let you do a dry run, remove the echo if you like the output
find /path/to/toplevel -type d -mtime +7 -exec echo rm -rf {} +
Update
If you have an older version of find that doesn't comply with POSIX 2004 then use this instead:
find /path/to/toplevel -type d -mtime +7 -exec echo rm -rf {} \;
or
find /path/to/toplevel -type d -mtime +7 -print0 | xargs -0 echo rm -rf {}
The former terminated by \; will call rm for each directory it finds, the latter with xargs will attempt to call rm as few times as possible by passing multiple directories to a single call to rm and thus be much faster. The latter also has identical behavior to the first one terminated with a +

Resources