GNU find

find – search for files in a directory hierarchy

General

Global Options

-maxdepth levelsDescend at most levels (a non-negative integer) levels of directories below the starting-points
-mount
-xdev
Don’t descend directories on other filesystems

Tests

-name patternBase of file name (the path with the leading directories removed) matches shell pattern pattern
-user unameFile is owned by user uname (numeric user ID allowed)

Tasks

Move all matching files to a special directory

find . -name "pattern*" -type f -print0 | xargs -r0 /bin/mv -t /path/to/directory/

Find files NOT matching a pattern

find . ! -name "*20.04*"
find . ! -name "*20.04*" -delete

Find files with forbidden characters in SMB

find /projects/ -regex '.*[\:*?"<>|]+.*'

Find files with a trailing whitespace

find /projects/ -regex '.* $'

Delete empty directories

find . -type d -empty -delete

List directory, outputs only the last part and sort it

find /my/path -mindepth 1 -maxdepth 1 -type d -printf "%f\n" | sort -n

Clean and rename files

find . -regex '.* $' -or -regex '.*[\:*?"<>|]+.*' -exec /home/leo/filename_cleaner '{}' \;

with filename_cleaner:

#!/bin/sh

echo "old filename: $1"
oldfilename=$1
newfilename=`echo $1 | sed 's/\(.*\) $/\1/' | sed 's/[\:*?"<>|]//g'`
echo "new filename: $newfilename"
mv -vi "$1" "$newfilename"

Remove old files

Remove recursively all files that are older than 3 months

From the find man page:

  • -type f regular file
  • -mtime n File’s data was last modified n*24 hours ago
  • -delete Delete files; true if removal succeeded.
find /var/log/ -type f -mtime +90 -delete -print

Set permissions right

We want to set the permissions of:

  • directories to 770 which is rwx for user (owner) and group (execute for folders allows to list contents)
  • files to 660 which is rw for user and group
find mydir -type d -exec chmod 770 '{}' \;
find mydir -type f -exec chmod 660 '{}' \;

The problem here is that we’re doing two passes. This is acceptable on a small scale, but it might be taxing on big volumes.

Expressions

using :

leo@computer:~$ find test/
test/
test/file01.txt
test/file02.jpg
test/file03.zip

Or:

leo@computer:~$ find test/ -name *.zip -or -name *.jpg
test/file02.jpg
test/file03.zip

Not:

leo@computer:~$ find test/ -not -name *.zip
test/
test/file01.txt
test/file02.jpg