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


22

Bad Things ® ™. It's (almost) the equivalent of sudo rm -rf / - it will, as root, find all files or directories starting from / and recursively descending from there, and then execute the rm command against each file/directory it finds. It won't actually delete directory entries as there's no -f or -r options passed to rm, but it will remove all ...


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

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


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.


10

Use this with bash: find $1 -name "* *.xml" -type f -print0 | \ while read -d $'\0' f; do mv -v "$f" "${f// /_}"; done find will search for files with a space in the name. The filenames will be printed with a nullbyte (-print0) as delimiter to also cope with special filenames. Then the read builtin reads the filenames delimited by the nullbyte and ...


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

You could use find /var/dtpdev/tmp/ -type f -mtime +15, this would find all files older than 15 days. If you add -exec rm -f {} \; then it would also delete them, the whole command would be: find /var/dtpdev/tmp/ -type f -mtime +15 -exec rm -f {} \;


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

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


8

Using rename find . -type f -name "* *.xml" -exec rename "s/\s/_/g" {} \; or with $1 find "$1" -type f -name "* *.xml" -exec rename "s/\s/_/g" {} \; Using mv find . -type f -name "* *.xml" -exec bash -c 'mv "$0" "${0// /_}"' {} \; or with $1 find "$1" -type f -name "* *.xml" -exec bash -c 'mv "$0" "${0// /_}"' {} \;


7

The solution that might work for your case is, find . -type d '!' -exec test -e "{}/utilities.py" ';' -print Testing I created 4 sub directories named dir1, dir2, dir3 and dir with spaces. I wanted to test if this handles spaces equally well which is why I created a directory with spaces in its name. I created files file1, file2, file3 and file4 in ...


7

Let us suppose that we have file1 in the current directory. Then: $ find . -maxdepth 0 -name "file1" $ find . file1 -maxdepth 0 -name "file1" file1 Now, let's look at what the documentation states: -maxdepth 0 means only apply the tests and actions to the command line arguments. In my first example above, only the directory . is listed on 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"



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