Tag Info

Hot answers tagged

43

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.


25

Why do so difficult with -regex? Just do it with -name find -type f -name "[[:upper:]]*"


25

From the findutils find manpage: If no expression is given, the expression -print is used (but you should probably consider using -print0 instead, anyway). (-print is a find expression.) The POSIX documentation confirms this: If no expression is present, -print shall be used as the expression. So find . is exactly equivalent to find . -print; ...


24

That's a really nice catch. From a quick look at the source code for GNU find, I would say this boils down to how fnmatch behaves on invalid byte sequences (pred_name_common in pred.c): b = fnmatch (str, base, flags) == 0; (...) return b; This code tests the return value of fnmatch for equality with 0, but does not check for errors; this results in any ...


20

The quotes protect the contents from shell wildcard expansion. Run that command (or even simpler just echo *test.txt in a directory with a footest.txt file and then one without any files that end in test.txt and you will see the difference. $ ls a b c d e $ echo *test.txt *test.txt $ touch footest.txt $ echo *test.txt footest.txt The same thing will ...


14

-print is the default action. Some find predicates are considered as actions as opposed to filters or conditions. For instance, -type f is not an action. -exec is an action even though it can also be used as a condition. Actions include -print, -exec and -ok. Some find implementations have other non-standard action predicates like the -print0, -printf, ...


13

Never embed {} in the shell code! (by the way, some find implementations won't let you do that, and POSIX leaves the behaviour unspecified when {} is not on its own in an argument to find) find . -name accept_ra -exec sh -c 'echo 0 > "$1"' sh {} \; Or: find . -name accept_ra -exec sh -c 'for i do echo 0 > "$i"; done' sh {} + Note that the ...


13

find -name option uses shell pattern matching notation to perform matching filename. * is a pattern matching multiple characters, shall match a string of zero or more characters. find uses fnmatch to check pattern matching, so you can use ltrace to check the result: $ touch $'\U1212'aa $ touch D$'\351'sinstaller $ LC_ALL=en_US.utf8 ltrace -e fnmatch find ...


12

That has nothing to do with bash or sudo. The find command is using the -exec action to run the given command on each file found. In this case, the command being run is touch -d @0 If you check man touch on a GNU system, you will find that -d, --date=STRING parse STRING and use it instead of current time So, the -d is a way of choosing ...


12

You can prevent the file from reaching xargs using: find . -maxdepth 1 -type f ! -name sums.sha1 -printf '%P\n' | xargs -r shasum -- > sums.sha1 To prevent problems with filename that have blanks or newlines or quotes or backslashes, I would however use: find . -maxdepth 1 -type f ! -name sums.sha1 -printf '%P\0' | xargs -r0 shasum -- > ...


11

There are errors in your assumptions, but first some background: You should discern two uses of -exec: with \; the {} will be replaced by a single item found with + the {} will be replaced by many items (as many as the commandline can hold). Therefore your example of -exec use invokes as many cp command as items found by find. Using find ... -exec ...


11

A long time ago (in 7th edition, 32V, 4.2BSD, 4.3BSD), at the system-call level a zero-length pathname denoted the current working directory (when used for lookup; it was disallowed when trying to create or delete a file or directory). In System III, it was an error to use a zero-length pathname under all circumstances, and the POSIX standard has this to say ...


11

Here is a general pattern: find /directory/containing/files -type f -exec grep -H 'pattern_to_search' {} + Here at first find will search all files in the directory containing necessary files, you can also use wildcards e.g. *.txt to look for only files ending with .txt. In that case the command would be: find /directory/containing/files -type f -name ...


10

List files in /tmp only: cd /tmp find . ! -name . -prune -path './????' -type f List files in /tmp recursively: find /tmp -path '*/????' -type f


10

See the man page for updatedb, "If the database already exists, its data is reused to avoid rereading directories that have not changed". Whereas the find command traverses all directories regardless of whether they have changed.


9

With GNU mv: find path_A -name '*AAA*' -exec mv -t path_B {} + That will use find's -exec option which replaces the {} with each find result in turn and runs the command you give it. As explained in man find: -exec command ; Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments ...


9

I can think of two possible solutions: If you have installed mv from GNU coreutils (which probably is the case), then the following command... find / -name "HAHA" -type f -exec mv --backup=numbered "{}" /home \; ...will move all files called HAHA to /home. The --backup=numbered option of mv ensures that every time the mv command executes, it will check ...


8

The reason why the find command is slow That is a really interesting issue... or, honestly, mallicious: The command find . -mindepth 2 -mtime +5 -print -delete is very different from the usual tryout variant, leaving out the dangerous part, -delete: find . -mindepth 2 -mtime +5 -print The tricky part is that the action -delete implies the option ...


8

You can just do the whole thing with (GNU) find and sort, no need for du: $ find . -iname '*png' -printf '%s %p\n' | sort -rn 68109 ./7.png 21751 ./2.png 21751 ./1.png 5393 ./6.png 2542 ./5.png 1717 ./4.png 1003 ./3.png 878 ./10.png 793 ./9.png 587 ./8.png


8

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


8

A -exec needs to be terminated with a ; or a +. The ; causes the command to execute once per found filename, whereas + causes the command to be executed once for all filenames. Here is a working example: find ! -iname "*.JPG" -exec dirname {} \; Some notable differences from your attempts: There must be a space between {} and \; The ; must be escaped, ...


8

If you want to crawl on dirs and subdirs: find /home/place/to/crawl -type f -exec file --mime-type {} \; | awk '{if ($NF == "image/jpeg") print $0 }' What it does? Search all inodes with the type file Execute the command file, to get a jpeg header of the file like: image/jpeg awk Edit: Added @Franklin tip, to use file with -i to use the mime string ...


8

The basic format of find is find WHERE WHAT So, in find *, the * is taken as the WHERE. Now, * is a wildcard. It matches everything in the current directory (except, by default, files/directories starting with a .). The Windows equivalent is *.*. This means that * is expanded to all files and directories in your current directory before it is passed to ...


7

POSIX defined find -exec utility_name [argument ...] {} + as: The end of the primary expression shall be punctuated by a <semicolon> or by a <plus-sign>. Only a <plus-sign> that immediately follows an argument containing only the two characters "{}" shall punctuate the end of the primary expression. Other uses of the ...


7

Simple use: find . -size +1M -delete If you insist using xargs and rm with find, just add -print0 in your command: find . -size +1M -print0 | xargs -r0 rm -- Other way: find . -size +1M -execdir rm -- {} + From man find: -print0 True; print the full file name on the standard output, followed by a null character (instead of the newline ...


7

As a start, you could print out files with a .jpg file extension with: sudo find / -name *.jpg -print See how that behaves, modify to suit, and you can then pipe the output into another function rather than just printout if you'd like. For example, if you want to allow .JPG as well: sudo find / -iname "*.jpg"


7

If you want to list files containing a JPEG image regardless of the extension in the filename, you could use find + file to list the files with mime type image/jpeg: find . -type f -exec sh -c ' file --mime-type "$0" | grep -q image/jpeg\$ && printf "$0\n" ' {} \; or find . -type f -exec sh -c ' mt=$(file --brief --mime-type "$0") [ ...


7

They are the same, they both write out the entire directory hierarchy from the current directory. From POSIX find documentation: The following commands are equivalent: find . find . -print


7

If you understand the && and || operators in the shell (and also in C, C++, and derivative languages), then you understand -a and -o in find. To refresh your memory: In the shell, command1 && command2 runs command1, and, if it (command1) succeeds, it (the shell) runs command2. command1 || command2 runs command1, and, if it (command1) fails, ...



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