Hot answers tagged

25

-delete implies -depth that doesn't work with -prune (-depth starts with the leaves). There's a warning about that in the manual of the GNU version (-delete is a GNU extension now also supported by FreeBSD find). info find --index-search=-delete The use of the '-delete' action on the command line automatically turns on the '-depth' option (*note ...


10

This is a performance issue of find. In findutils version 4.3.4, a workaround had to restrict the number of arguments that -execdir ... {} + will use to 1. In version 4.5.9 the limit was removed. See an example: $ mkdir -p dir{1..3} $ touch dir{1..3}/file1 dir2/file{1..3} $ find . ./dir1 ./dir1/file1 ./dir2 ./dir2/file1 ./dir2/file2 ./dir2/file3 ./dir3 ...


5

Just use -print flag: find /tmp -type f -mtime +2 -name "DBG*" -exec rm {} \; -print or, if rm supports the -v option, let rm do it all: find /tmp -type f -mtime +2 -name "DBG*" -exec rm -v {} + or if your find supports -delete: find /tmp -type f -mtime +2 -name "DBG*" -delete -print (note that the first two have a race condition that could allow ...


4

You're missing the a $ in front of the variable. Here, I'd do: if find "$full_path_trace" -name '*.trc' -mtime +5 -print -quit | grep -q '^'; then echo 'Success!' else echo >&2 fail fi Drop the -quit if your find doesn't support it. grep -q returns true as soon as a line is found in the input. -quit would cause find to exit upon the first ...


3

There's two issues; how cd behaves, which is easy to test via: bash-4.1$ mkdir first second bash-4.1$ cd first second bash-4.1$ pwd /home/jdoe/first bash-4.1$ So cd for this shell is going to the first item found. Second, find itself may or may not be doing any sorting of the results, and for directories (probably) only has a -d or "find first by depth" ...


3

It's so much easier with zsh globs here: for f (**/*.xml(.)) (mv -v -- $f **/$f:r:t(/[1])) Or if you want to include hidden xml files and look inside hidden directories like find would: for f (**/*.xml(.D)) (mv -v -- $f **/$f:r:t(D/[1])) But beware that files called .xml, ..xml or ...xml would become a problem, so you may want to exclude them: setopt ...


3

The first versions of Unix happened to use 512-byte blocks in their filesystem and disk drivers. Unix started out as a pretty minimalist and low-level system, with an interface that closely followed the implementation, and leaked details that should have remained abstracted away such as the block size. This is why today, “block” still means 512 bytes in many ...


3

Blocks were more important than bytes because from the beginning, files used a given number of blocks rather than bytes on the file system. A file with one byte still took up one block on the disk. For instance the find(1) manual page from Unix 6th edition says -size n True if the file is n blocks long (512 bytes per block). ...


3

find uses a depth-first strategy (as opposed to breadth-first), whether -depth is specified or not. -depth only guarantees that sub-directories are processed before their parents. A quick example: mkdir -p a/{1,2,3} b c find . produces . ./a ./a/2 ./a/1 ./a/3 ./b ./c whereas find . -depth produces ./a/2 ./a/1 ./a/3 ./a ./b ./c .


3

Your synopsis suggests that options must come before tests and both options and tests must come before actions, but that is not true. In fact, they can go in any order. Furthermore, there is fundamentally no difference between what the GNU find manpage calls tests and what it calls actions. I don't know why the manpage categorizes them differently in the ...


2

You can try this command instead : find /etc/home -type f -size +1G ! -name "*.zip" | xargs rm if you insist on using the -delete construct, please note that this option turns on the -depth switch in find and will reach in any subdirectory under /etc/home and find matching files for this criteria and delete them. If you are okay with that, just replace ...


2

Two points: find "ignores fractional parts". I guess it calculates the number of hours, divides by 24, and integerizes the result (discards the fraction). So -mtime 0 checks a file, compares the mtimes, converts to hours, divides by 24. If the integer part of that result is 0, it's a match. That means 0.99999 hours ago will match. Then -mtime +0 matches any ...


2

A command line program can take input from a user via two sources: from stdin (which you are piping to), and by attaching directly to the TTY. Bad things can happen when these are mixed up. Vim does not want to read input from a pipe, it wants you, the user, directly. So let's give it the real stdin back. As a solution, we can use a command substitution to ...


2

The syntax for find is: find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression] In your case -iname and -type are both expressions. So, there is no problem with using one before another. From Description: GNU find searches the directory tree rooted at each given file name by evaluating the given expression from left to right, according to ...


2

When you use inline script with find ... -exec sh -c ..., you should pass find result to the shell through positional parameter, then you don't have to use {} everywhere in your inline script. If you have bash or zsh, you can pass basename output through printf '%q': find . -name "*.xml" -exec bash -c ' for f do BASENAME="$(printf "%q" "$(basename -- ...


1

The following is a relatively straightforward, POSIX-compliant pipeline. It scans the hierarchy twice, first for directories and then for *.xml regular files. A blank line between scans signals AWK of the transition. The AWK component maps basenames to destination directories (if there are multiple directories with the same basename, only the first ...


1

Multiple immediate options: find /tmp -type f -mtime +2 -name "DBG*" -exec echo {} \; -delete or find /tmp -type f -mtime +2 -name "DBG*" -exec echo {} \; -exec rm {} \;


1

There must be whitespace in front of the ;: find "${listener}/tracefiles/${listener}.log" -exec cp /dev/null {} \; But it doesn't make any sense to call find -exec for a single file. Why don't you use test -f "${listener}/tracefiles/${listener}.log" && cp /dev/null "${listener}/tracefiles/${listener}.log"


1

Try: find /some/path -name DRR_O_sql\* -mtime +3 -type f -exec mv "{}" /home/backup \; /some/path is your source. Note that this will not preserve directory structures.


1

Replace ; with + at the end. From the manpage: -execdir command {} + Like -exec, but the specified command is run from the subdirectory containing the matched file, which is not normally the directory in which you started find. This a much more secure method for invoking commands, as it avoids race ...


1

find traverses files in whatever order the filesystem returns. This order is not predictable; creating, removing or renaming a file can change the order of other files in the same directory. It's a toss-up whether find / -type d -name myDir returns /usr/myDir or /home/myDir first, and it could change at any time. (In this specific example, it probably won't ...


1

your question is not entirely clear to me, but if you have a dir structure as follows -- a a/data a/data/file1 a/studyName a/studyName/data a/studyName/data/file1 a/studyName/data/file2 a/studyName/data/file3 and you're looking for studyName/data/fileX, you could do -- find . -path "*studyName/data*" -type f ./a/studyName/data/file1 ...


1

Using your terminology, options, tests and actions can be intermixed: find / -type f -name '*.DELETE' -ls -delete -o -name '*.COMPRESS' -exec gzip {} \;


1

You can just discard those errors and ignore the exit status: find /tmp -name dsm\* -type f 2> /dev/null || : If you still want to keep find's stderr, to still be able to see errors other than failure to enter or list directories because of access permission restriction, you could try and use a syntax that detects those permission issues, but that's ...


1

After trying the first answer and toying with it a little I found that it can be done slightly shorter and less complex using -execdir: find . -type f -name 'file*' -execdir mv {} {}_renamed ';' Looks like it should also do exactly what you need.


1

The following command not only find you the top 50 largest files (>100M) on your filesystem, but also sort (GNU sort) by the biggest: find / -xdev -type f -size +100M -exec du -sh {} ';' | sort -rh | head -n50 -xdev Don't descend directories on other filesystems. On BSD find use -x which is equivalent to the deprecated -xdev primary. For all ...


1

With zsh: mylist=(${(f)"$(<filelist)"}) print -rl -- *(.^e_'(($mylist[(Ie)$REPLY]))'_) It reads the lines of filelist in an array and then uses glob qualifiers/estring to glob/select only the file names not present in the array: the . selects only regular files (add D if your list contains dotfiles) and the negated ^e_'expression'_ further selects only ...



Only top voted, non community-wiki answers of a minimum length are eligible