BASH Find

From Indie IT Wiki

Find Files Named Containing Pattern

find . -type f -name 'docker-compose.yml' -exec grep -H 'restart' {} \;

Find Files Not Matching A Pattern

find . -type f -not -name "*.html"

Find Files Not Matching Multiple Patterns

find . -type f -not \( -name "*.mkv" -o -name "*.mp4" \)

Delete Files Not Matching A Pattern

find . -type f -not -name "*.html" -exec rm -fv {} \;

Find Unique Duplicate Files

If you're looking for identical files (with the same md5 sum)...

find . -type f -exec md5sum {} \; | sort | uniq -d --check-chars=32

Thanks

Rename Part Of Filename

Pure BASH Method

This will change a character, such as a dash for an underscore in all the files in this folder ...

for i in *; do mv -- "$i" "${i//-/_}"; done

renamed '34001-1.jpg' -> '34001_1.jpg'
renamed '34001-2.jpg' -> '34001_2.jpg'

Using Rename

This will rename all files by removing what is after the episode number and before the extension.

e.g.

Some Show S03E01 The Episode Title.mp4

Command (test and verbose):

rename -n -v -e 's/E(\d+).*/$1\.mp4/' *.mp4

Output:

rename(American Dad! S05E01 1600 Candles.mp4, American Dad! S0501.mp4)
rename(American Dad! S05E02 The One That Got Away.mp4, American Dad! S0502.mp4)
rename(American Dad! S05E03 One Little Word.mp4, American Dad! S0503.mp4)

Command:

rename -v -e 's/E(\d+).*/$1\.mp4/' *.mp4

Output:

American Dad! S05E01 1600 Candles.mp4 renamed as American Dad! S0501.mp4
American Dad! S05E02 The One That Got Away.mp4 renamed as American Dad! S0502.mp4
American Dad! S05E03 One Little Word.mp4 renamed as American Dad! S0503.mp4

Thanks - https://superuser.com/questions/496403/rename-every-file-in-a-directory-to-remove-part-of-filename#496411

Find Oldest File

find -type f -printf '%T+ %p\n' | sort | head -n 1

Find Using Text File List

mkdir -p /tmp/{0..9}
find /tmp/ > /tmp/dirs
find $(cat /tmp/dirs) -type d -name "8"

Good Examples

https://www.linux.com/community/blogs/133-general-linux/732993

Add Text To End Of All Lines In A Text File

sed -e 's/$/ yes/' ham_emails_new.txt > ham_emails_newer.txt

Add Text To Beginning Of All Lines In A Text File

sed -e 's/^/FromOrTo: /' ham_emails.txt > ham_emails_new.txt

Find Email Address From Text File

cat textfile.txt | grep -i -o '[A-Z0-9._%+-]\+@[A-Z0-9.-]\+\.[A-Z]\{2,4\}'

Extract Certain Headers And Body Of Email

cat `find . -type f ` |formail -c -k -X From: -X Subject: |egrep -v '^--|^<|^Content|charset|^Sent|^This|^$'

cat `find . -type f ` |formail -c -d -k -X From: -X Subject: -s |egrep -v '^--|^<|^Content|charset|^Sent|^This|to be clean.$|=$|$|^$'

Find And Copy Files To A Different Directory

Find any text files, then copy them to a different directory.

find . -name "*.txt" -exec cp {} /path/to/directory \;

Find And Copy Files With Directory Structure

find /path/to/search/ -type f -name '*.mov' -print -exec cp --parents "{}" /path/to/copy/to/ \;

Date Yesterday

date -d "1 day ago" '+%Y-%m-%d'

Last X Command Used

Find the last time you used tar...

!tar:p

Run that same command again...

!tar

Thanks to CLIMagic

Files Matching Pattern And Remove File Extension

for FILE in *.conf; do echo "${FILE%%.*}"; done

Largest Directories Or Files

Directories...

du -Sh | sort -rh | head -n 15

Files...

find . -type f -exec du -Sh {} + | sort -rh | head -n 15

Thanks to Xmodulo.com

Find And Tar Files

The + means tar will only be called once...

find . -type f -exec tar -czvf backup.tar.gz '{}' \+;

Working example...

find public_html/app/design/frontend/ public_html/skin/frontend/ -type f -mtime -12 -print -exec tar -czvf paullys_tweaked_files.tar.gz '{}' \+;

Text In Types Of Files

find . -type f -name '*.doc' -exec grep -Hn "text here" {} \;

Find Then Rename / Add Extension To All Files

find . -type f -exec mv '{}' '{}'.jpg \;

Files Owned By A User

find /path/to/search/ -user nobody -print

Zero Length Files

find /path/to/search/ -size 0

e.g.

Find any zero length files named tmp.* older than 1 day and delete them...

find /tmp/ -type f -size 0 -name 'tmp.*' -mtime +1 -exec rm -rf {} \;

Find And Delete

Find any files older than 7 days, then delete them but show what you are deleting.

find /path/to/directory -type f -mtime +7 -exec rm {} \; -print

Find And Move

Find any text files, then move them to a different directory.

find . -name "*.txt" -exec mv {} /path/to/directory \;

Files Newer Than Another File

touch --date "2011-12-31" /tmp/foo
touch /tmp/bar
find /tmp/ -type f -newer /tmp/foo

Files Older Than X File

find /path/to/search -type f -name 'fish' \! -newer /path/to/search/in/fish \! -samefile /path/to/search/in/fish |sort

e.g.

find /home/MailScanner/archive-nfs/ -type f -name 'messages' \! -newer /home/MailScanner/archive-nfs/20150327/messages \! -samefile /home/MailScanner/archive-nfs/20150327/messages |sort

Text Files Created In The Last 30 Days

This will find *.txt files...

find ~/Documents/ -type f -mtime -30 -name '*.txt' -print

This will find true ASCII files...

find ~/Documents/ -type f -mtime -30 -print -exec file {} + | grep ASCII

Most Recently Changed Files

find . -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort

Multiple File Types

find /path/to/search/ -type f \( -name "*.epub" -or -name "*.mobi" \) -printf '%f\n' |sort |uniq

Empty Directories / Folders

find . -empty -type d

Space Used In Folder And Sort By Size

cd /home/user/
du -sch .[!.]* * |sort -h

or

du -sch /home/user/.[!.]* /home/user/* |sort -h

All Email Forward Files And Show Contents

find /home/ -maxdepth 2 -type f -name '.forward' -printf "\n%p\n" -exec cat {} \;