GNU find
- General
- Tasks
- Move all matching files to a special directory
- Find files NOT matching a pattern
- Find files with forbidden characters in SMB
- Find files with a trailing whitespace
- Delete empty directories
- List directory, outputs only the last part and sort it
- Clean and rename files
- Remove old files
- Set permissions differently on folders and files (several filter/action)
- Expressions
find – search for files in a directory hierarchy
General
Global Options
-maxdepth levels | Descend at most levels (a non-negative integer) levels of directories below the starting-points |
-mount | Don’t descend directories on other filesystems |
Tests
-name pattern | Base of file name (the path with the leading directories removed) matches shell pattern pattern |
-user uname | File 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 differently on folders and files (several filter/action)
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 '{}' \; \) , \( -type f -exec chmod 660 '{}' \; \)
This is achieved in one pass.
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