Hot answers tagged

214

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.


180

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 well;...


106

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 ''...


93

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 locate(...


90

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


89

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\)"


85

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 "$...


69

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 ...


63

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


59

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 …) ...


59

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 ...


58

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. ...


49

-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 ...


46

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 . ...


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.


45

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.


42

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 ...


42

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' {} \; &...


41

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 ...


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.


41

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 ...


40

Be careful with special file names (spaces, quotes) when piping to rm. There is a safe alternative - the -delete option: find /path/to/directory/ -mindepth 1 -mtime +5 -delete That's it, no separate rm call and you don't need to worry about file names. Replace -delete with -depth -print to test this command before you run it (-delete implies -depth).


39

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


35

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


35

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"))))' ...


35

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 ...


35

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 ...


34

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 '*[0-9]x[0-9]*[...


30

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, ...


30

you can filter out messages to stderr. I prefer to redirect them to stdout like this. find / -name art 2>&1 | grep -v "Permission denied" Explanation: In short, all regular output goes to standard output (stdout). All error messages to standard error (stderr). grep usually finds/prints the specified string, the -v inverts this, so it finds/...



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