Hot answers tagged

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.


26

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


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


17

find . -type f ! -newermt "31 Dec 2014" find(1): -newerXY reference Compares the timestamp of the current file with reference. The reference argument is normally the name of a file (and one of its timestamps is used for the comparison) but it may also be a string describing an absolute time. X and Y are ...


14

find traverses the specified directory tree(s), and evaluates the given expression for each file that it finds. The traversal starts at the given path. Here's a summary of how find . -name foo operates: First path on the command line: . Does the base name (.) match the pattern foo? No, so do nothing. It so happens that /tmp/foo is another name for the ...


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


12

If you have GNU find, you can use -printf: find content/media/ -type f -printf '%p : %u : %g : %k'


12

GNU find has an optimization which can be applied to find . but not to find . -type f: if it knows that none of the remaining entries in a directory are directories, then it doesn't bother to determine the file type (with the stat system call) unless one of the search criteria requires it. Calling stat can take measurable time since the information is ...


11

If you run this command your touch file will be run, potentially multiple times, from the directory in which the command has been started: find -name '*.pdf' -exec touch file \; On the other hand, if you run this variant, each instance of the command will be run in the target file's directory: find -name '*.pdf' -execdir touch file \; In both cases you ...


11

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


11

Found the details here: The -exec action causes another program to be run. It passes to the program the name of the file which is being considered at the time. The invoked program will typically then perform some action on that file. Once again, there is a race condition which can be exploited here. We shall take as a specific example the command ...


11

Use stat on the -exec action of find: find .content/media/ -type f -exec stat -c '%n : %U : %G : %s' {} + Change the format sequences of stat to meet your need.


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


10

You are on the right track (for a simpler solution, running only 2 or 3 commands, see below). You should use * instead of ./ to get rid of the current directory¹ and this simplifies cutting of the milliseconds somewhat, then just pipe the result into GNU parallel or xargs²: find * -type d | cut -c 1-10 | parallel date --date=@{} +%c to get Sat 12 Sep ...


10

I'd avoid running several commands per file in a loop. Since you're already using GNUisms: find . ! -name . -prune -type d | awk '{t = substr($0, 3, 10); print t, strftime("%a %b %d %T %Z %Y", t)}' Which just runs two commands. strftime() is GNU-specific, like date -d.


10

It's not an endless looping, it's just GNU find reporting that echo died of a SIGPIPE (because the other end of the pipe on stdout has been closed when head died). -execdir is not specified by POSIX. And even for -exec, there's nothing in the POSIX spec that says that if the command is killed by a SIGPIPE, find should exit. So, would POSIX specify ...


10

These examples work in any POSIX shell and require no external programs. This stores the Part*.mp3 files at the same level as the Project directory: (cd Project && for i in Part*/audio.mp3; do echo mv "$i" ../"${i%/*}".mp3; done) This keeps the Part*.mp3 files in the Project directory: for i in Project/Part*/audio.mp3; do echo mv "$i" ...


10

Use -prune to ignore those directories: find /path/to/directory -name '*[0-9]*' -prune -o -type d -print though if you're on a gnu setup you may want to use the C locale when running the above, see Stéphane's comment below.


10

You can use fdupes. 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. You can call it like fdupes -r /path/to/dup/directory and it will print out a list of dupes. Update You can give it try to fslint also. After setting up fslint, go to ...


9

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// /_}"' {} \;


9

Yes, there are several ways to accomplish this with the find command. I'll list some in the order that I think is important for understanding in your situation. Your script appears to accept multiple filename arguments, so the most efficient and nearly universal way to accomplish this using the find command is: find ~/foo -type f -name \*.txt -exec perl ...


9

That's because grep can't read file names to search through from standard input. What you're doing is printing file names that contain XYZ. Use find's -exec option instead: find . -name "*ABC*" -exec grep -H 'XYZ' {} + From man find: -exec command ; Execute command; true if 0 status is returned. All following arguments to find ...


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

Don't run it. This will find everything (all files, directories, links, sockets etc) under / i.e. everything in the system and then it will try to remove those one at a time with rm. Note that as there is no -r option with rm, only the directory entries will not be removed, everything else will be gone.


8

You already have: find ./ -type d | cut -c 3-12 which presumably gets you the timestamps in epoch format. Now add a while loop: find ./ -type d | cut -c 3-12 | while read datestamp do printf %s "$datestamp" date -d "@$datestamp" done Note though that in some shells, that syntax gets the while loop in a subshell, which means that if you try to ...


8

You can combine multiple predicates by chaining them. There's no -oldermt, but you can write that as -not -newermt. You want: -newermt '-15 seconds' to say the file is less than 15 seconds old, and -not -newermt '-2 seconds' to say the file is more than 2 seconds old Try: find /my/directory -newermt '-15 seconds' -not -newermt '-2 seconds' Or, to ...


8

I would execute a find inside another find. For example, I would execute this command line in order to list the files that would be removed: $ find /path/to/source -type d -name 'rules' -exec find '{}' -mindepth 1 -maxdepth 1 -type f -iname '*.pdf' -print ';' Then, after checking the list, I would execute: $ find /path/to/source -type d -name 'rules' ...


7

On my computer when I use: find . \( -name dirname -type d \) -exec rm -r '{}' ';' The directories are deleted but I get the error: find: ‘./dirname’: No such file or directory for each directory. My directories aren't empty, so the -delete option won't work for me. I found the reason for this behavior here: find takes (not necessarily) the ...



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