Find: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 108: Line 108:


=Iterating over <tt>find</tt> Results in Scripts=
=Iterating over <tt>find</tt> Results in Scripts=
<syntaxhighlight lang='bash'>
while IFS= read -r -d '' file
do
  (( count++ ))
  echo "Playing file no. $count"
  play "$file"
done <  <(find mydir -mtime -7 -name '*.mp3' -print0)
echo "Played $count files"
</syntaxhighlight>
Borrowed from https://github.com/koalaman/shellcheck/wiki/SC2044
⚠️ The following is a less safe form, it is frowned upon by spellcheck: "For loops over find output are fragile. Use find -exec or a while read loop." See: {{External|https://github.com/koalaman/shellcheck/wiki/SC2044}}
This protects against paths with spaces in them:
This protects against paths with spaces in them:
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
Line 117: Line 132:
IFS="$(printf ' \t\n\r')"
IFS="$(printf ' \t\n\r')"
</syntaxhighlight>
</syntaxhighlight>
⚠️ This pattern is frowned upon by spellcheck: "For loops over find output are fragile. Use find -exec or a while read loop." See: {{External|https://github.com/koalaman/shellcheck/wiki/SC2044}}

Revision as of 23:34, 17 July 2023

Internal

Numeric Arguments

All numeric arguments are interpreted as follows:

+n for greater than n
n for exactly n
-n for less than n

Other Arguments

-print

It prints the pathname of the current file to standard output

Target Type

find . -type <type-identifier>

where the type identifier can be:

  • f regular file
  • d directory
  • l symbolic link
  • b block special
  • c character special
  • p FIFO
  • s socket

Case Insensitive Search

find . -iname ...

Control Descend Depth

The upper and lower limit of the descend depth can be controlled with -mindepth and -maxdepth, as follows:

find . -mindepth n

Configure find to apply tests and action at levels equal or deeper than n. -mindepth 1 processes the content of the directory specified as argument and recursively the content of its sub-directories.

find . -maxdepth n

Configure find to descend at most n directory levels below the command line arguments. -maxdepth 0 limits the whole search to the command line arguments.

In order to access directory between an upper and lower depth limit, both -mindepth and -maxdepth should be used.

Time Constraints

For interpretation of numeric arguments (+-n), see: Numeric Arguments.

Time flags:

  • -amin n - file was accessed n minutes ago.
  • -anewer file - file was accessed more recently than file was modified.
  • -atime n - file was accessed n * 24 hours ago. When find figures out how many 24-hour periods ago the file was last accessed, the fractional part is ignored, so to match -atime + 1, a file has to have been accessed at least two days ago.
  • -cmin n - file's status was last changed n minutes ago
  • -cnewer file
  • -ctime n - file's status was last changed n*24 hours ago. See the comments for -atime to understand how rounding affects the interpretation of file status change times.
  • -mmin n -
  • -mtime n - file's data was last modified n*24 hours ago. See the comments for -atime to understand how rounding affects the interpretation of file modification times.

Find all files modified less that 2 days ago

find . -mtime -2

-name Patterns

A pattern for file names with specific characters on specific positions can be specified with [...]:

find . -name *.[jw]ar

looks for *.jar and *.war.

For more complex expression syntax, see Expressions below.

Mac Detail

On Mac, the pattern must be specified between quotes:

find . -name "*.something"

Expressions

"-name pattern" is an expression. Multiple expressions can be combined using the operators -not, -and and -or.

Example:

find . -name '*.jar' -and -not -name '*-source.jar'

Filtering "." out from the directory list:

find . -type d -not -name '.'

Exec

find . -exec command {} \;
find mydir -name '*.mp3' -exec sh -c '
    echo "Playing ${1%.mp3}"
    play "$1"
  ' sh {} \;

Iterating over find Results in Scripts

while IFS= read -r -d '' file
do
  (( count++ ))
  echo "Playing file no. $count"
  play "$file"
done <   <(find mydir -mtime -7 -name '*.mp3' -print0)
echo "Played $count files"

Borrowed from https://github.com/koalaman/shellcheck/wiki/SC2044


⚠️ The following is a less safe form, it is frowned upon by spellcheck: "For loops over find output are fragile. Use find -exec or a while read loop." See:

https://github.com/koalaman/shellcheck/wiki/SC2044

This protects against paths with spaces in them:

declare -a files
IFS="$(printf '\n\r')"
for i in $(find "${user_level_toolbox_app_dir}" -name .history.json -type f); do
  files+=("${i}")
done
IFS="$(printf ' \t\n\r')"