Hot answers tagged

177

You missed a ; or a + and a {}: find . -exec grep chrome {} \; or find . -exec grep chrome {} + find will execute grep and will substitute {} with the filename(s) found. The difference between ; and + is that with ; a single grep command for each file is executed whereas with + as many files as possible are given as parameters to grep at once.


165

I'd strongly suggest not to use find -L for the task (see below for explanation). Here are some other ways to do this: If you want to use a "pure find" method, it should rather look like this: find . -xtype l (xtype is a test performed on a dereferenced link) This may not be available in all versions of find, though. But there are other options as ...


98

Short answer (closest to your answer, but handles spaces) OIFS="$IFS" IFS=$'\n' for file in `find . -type f -name "*.csv"` do echo "file = $file" diff "$file" "/some/other/path/$file" read line done IFS="$OIFS" Better answer (also handles wildcards and newlines in file names) find . -type f -name "*.csv" -print0 | while IFS= read -r -d ...


90

locate(1) has only one big advantage over find(1): speed. find(1), though, has many advantages over locate(1): find(1) is primordial, going back to the very first version of AT&T Unix. You will even find it in cut-down embedded Linuxes via Busybox. It is all but universal. locate(1) is much younger and nonstandard. The earliest ancestor of ...


86

Why not simply use this: find -name "*.xls" -o -name "*.csv" You don't need regex for this. If you absolutely want to use regex simply use find -regex ".*\.\(xls\|csv\)"


79

Recent versions of GNU find have an -iname flag, for case-insensitive name searches. find . -iname "WSFY321.c"


73

The find command is the primary tool for recursive, filesystem operations. Use the -type d expression to tell find you're interested in finding directories only (and not plain files). The GNU version of find supports the -empty test, so $ find . -type d -empty -print will print all empty directories below your current directory. Use find ~ -… or find ...


65

fdupes can do this. From man fdupes: Searches the given path for duplicate files. Such files are found by comparing file sizes and MD5 signatures, followed by a byte-by-byte comparison. In Debian or Ubuntu, you can install it with apt-get install fdupes. In Fedora/Red Hat/CentOS, you can install it with yum install fdupes. On Arch Linux you can use ...


58

yes, you can: find /media/d/ -type f -size +50M ! \( -name "*deb" -o -name "*vmdk" \) Explanation from the POSIX spec: ! expression : Negation of a primary; the unary NOT operator. ( expression ): True if expression is true. expression -o expression: Alternation of primaries; the OR operator. The second expression shall not be evaluated ...


54

With GNU find, you can use the -quit predicate: find . ... -print -quit If all you do is printing the name, and assuming the filenames don't contain newline characters, you could do: find . ... -print | head -n 1 That will not stop find after the first match, but possibly, depending on timing and buffering upon the second match or (much) later. ...


52

Well, the generic case that works with any command that writes to stdout is to use xargs, which will let you attach any number of command-line arguments to the end of a command: $ find … | xargs grep 'search' Or to embed the command in your grep line with backticks or $(), which will run the command and substitute its output: $ grep 'search' $(find …) ...


48

Try: find / -xdev -type f -size +100M It lists all files that has size bigger than 100M. If you want to know about directory, you can try ncdu. If you aren't running Linux, you may need to use -size +204800 or -size +104857600c, as the M suffix to mean megabytes isn't in POSIX. find / -xdev -type f -size +102400000c


46

Use the ? wildcard for file globbing: ls -d /tmp/???? This will print all files and directories whose filename is 4-char long. As suggested by @roaima, the -d flag will prevent ls to display the content of subdirectories that match the pattern.


41

The problem is, you didn't quote your -name parameter. Do this instead: find . -name '*.java' Explanation Without the quotes, the shell interprets *.java as a glob pattern and expands it to any file names matching the glob before passing it to find. This way, if you had, say, foo.java in the current directory, find's actual command line would be: find . ...


41

You need to quote your argument error* because the shell expands it. So what you're actually running now is find -name error_log, because that's what the shell can expand it to (there's a file named error_log in your current directory). find . -name 'error*' Is the correct invocation for your use case.


40

You can combine criteria with -o as suggested by Shadur. Note that -o has lower precedence than juxtaposition, so you may need parentheses. find . -name '*.jpg' -o -name '*.png' find . -mtime -7 \( '*.jpg' -o -name '*.png' \) # all .jpg or .png images modified in the past week On Linux, you can use -regex to combine extensions in a terser way. The ...


40

List the directories deeply-nested-first. find . -depth -type d -exec rmdir {} \; 2>/dev/null (Note that the redirection applies to the find command as a whole, not just to rmdir. Redirecting only for rmdir would cause a significant slowdown as you'd need to invoke an intermediate shell.) You can avoid running rmdir on non-empty directories by passing ...


38

-delete will perform better because it doesn't have to spawn an external process for each and every matched file. It is possible that you may see -exec rm {} \; often recommended because -delete does not exist in all versions of find. I can't check right now but I'm pretty sure I've used a find without it. Both methods should be "safe". EDIT per comment ...


37

If I understand you correctly this is what you want to do: find . -name '*.py' -print0 | xargs -0 grep 'something' > output.txt Find all files with extension py, grep only rows that contain something and save the rows in output.txt. If the file contains anything it will be replaced. Edit: Using -exec: find . -name '*.py' -exec grep 'something' {} \; ...


36

Combining GNU find options and predicates, this command should do the job: find . -type d -empty -delete -type d restricts to directories -empty restricts to empty ones -delete removes each directory The tree is walked from the leaves without the need to specify -depth as it is implied by -delete.


34

Some versions of sort have a -z option, which allows for null-terminated records. find folder1 folder2 -name "*.txt" -print0 | sort -z | xargs -r0 myCommand Additionally, you could also write a high-level script to do it: find folder1 folder2 -name "*.txt" -print0 | python -c 'import sys; sys.stdout.write("\0".join(sorted(sys.stdin.read().split("\0"))))' ...


33

Find can execute arguments with the -exec option for each match it finds. It is a recommended mechanism because you can handle paths with spaces/newlines and other characters in them correctly. You will have to delete the contents of the directory before you can remove the directory itself, so use -r with the rm command to achieve this. For your example you ...


33

Well, the simple answer is, I guess, that your find implementation is following the POSIX/SuS standard, which says it must behave this way. Quoting from SUSv4/IEEE Std 1003.1, 2013 Edition, "find": -mtime n      The primary shall evaluate as true if the file modification time subtracted      from the initialization time, divided by 86400 (with any ...


32

Assuming you just want the name of each directory: find /path/ -type d -print


31

Use the -o flag between different parameters. find ./ -type f \( -iname \*.jpg -o -iname \*.png \) works like a charm.


31

A string contains “a number followed by an x followed by a number” if and only if it contains a digit followed by an x followed by a digit, i.e. if it contains a substring matching the pattern [0-9]x[0-9]. So you're looking to remove the files whose name matches the pattern *[0-9]x[0-9]*[0-9]x[0-9]*.jpg. find /path/to/directory -type f -name ...


31

I'm not sure: grep -r -i 'the brown dog' /* is really what you meant. That would mean grep recursively in all the non-hidden files and dirs in / (but still look inside hidden files and dirs inside those). Assuming you meant: grep -r -i 'the brown dog' / A few things to note: Not all grep implementations support -r. And among those that do, the ...


29

You can also do this with just du. Just to be on the safe side I'm using this version of du: $ du --version du (GNU coreutils) 8.5 The approach: $ du -ah ..DIR.. | grep -v "/$" | sort -rh Breakdown of approach The command du -ah DIR will produce a list of all the files and directories in a given directory DIR. The -h will produce human readable sizes ...


29

As for the find command, you can also just add more -exec commands in a row: find . -name "*" -exec chgrp -v new_group '{}' \; -exec chmod -v 770 '{}' \; Note that this command is, in its result, equivalent of using chgrp -v new_group file && chmod -v 770 file on each file. All the find's parameters such as -name, -exec, -size and so on, ...


28

Use -prune on the directories that you're going to delete anyway to tell find not to bother trying to find files in them: find . \( -name build -o -name obj -o -name '*.so' \) -prune -exec rm -rf {} + Also note that *.so needs to be quoted as otherwise it may be expanded by the shell to the list of .so files in the current directory. The equivalent of ...



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