Date created: Sunday, August 30, 2020 7:34:34 PM. Last modified: Sunday, October 27, 2024 4:47:35 PM
'find' - Notes
Find by name and type:
# Files that don't end in ".mp3" or ".wav":
find . -not name "*.mp3" -not -name "*.wav" -type f
# Directories which contain "foo" in the name, case insensitive:
find . -iname "*foo*" -type d
Find by size:
# 70MBs and larger
find . -type f -size +70M
du -h -d 1 | sort -hr
Find by time:
# Last modified time is greater than 10 days: find /foo/ -mtime +10 # Last modified time is greater than 10 minutes find /foo/ -mmin +10 # Less than 10 minutes find /foo/ -mmin -10
Find and delete:
# Delete Mac OS .DS_Store and ._.DS_Store files
# Using "\;" calls rm for every file found
find . -name "*.DS_Store" -exec rm {} \;
# Using "+" calls rm once with all file names as arguments to speed up the process
find . -name "*.DS_Store" -exec rm {} +
# If files have spaces in the name/path, find can delete them using the -delete option because the spaces will cause -exec rm will fail
find . -name "*.DS_Store" -delete
Exec:
-exec runs the command from the current folder where find is being executed from.
-execdir run the command in the file where the found file is located.
# Recursively unrar archives in multiple sub-folders
find . -name '*.rar' -execdir unrar e {} \;
Exec with basename and renaming:
# -execdir executes the command inside the directory of the file returned by find, in the directory find is being run from:
find . -name "*.m4a" -execdir sh -c 'x="`basename \"{}\" .m4a`"; cp "$x".m4a "$x".copy' \;
# Convert files ending in m4a to mp3, using basename to get the original filename:
find . -iname "*.m4a" -execdir sh -c 'x="`basename \"{}\" .m4a`"; ffmpeg -i "$x".m4a -acodec libmp3lame -ab 320k "$x".mp3' \;
# Bash has a built-in string substitution feature which is less clunky than using basename:
ls *.m4a
aaa.m4a bbb.m4a ccc.m4a
find . -name "*.m4a" -execdir bash -c 'a="{}"; cp "$a" "${a/m4a/copy}"' \;
ls
aaa.copy aaa.m4a bbb.copy bbb.m4a ccc.copy ccc.m4a
Exec with escaping:
# Find files with a backslash in the name and use the -exec argument to launch a bash shell to rename the files
find . -name "*\\\*" -exec bash -c 'x="{}"; y="$(sed "s/\\\/-/g" <<< "$x")" && mv "$x" "$y" ' \;
Piping:
# When working with external commands find output can be piped to xargs verbatim...
find . -name "*.DS_Store" | xargs ...
# Or use -print to print each file/path separated by a new line
find . -name "*.DS_Store" -print0 | xargs ...
# or -print0 to print each file/path separated by a null character
find . -name "*.DS_Store" -print0 | xargs --null ...
find . -name "*.DS_Store" -print0 | xargs --null -I{} echo "Filename is {}" \;
Previous page: 'ethtool' - Notes
Next page: Get IP on CLI