Find: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
No edit summary
 
(33 intermediate revisions by the same user not shown)
Line 3: Line 3:
* [[Linux#Commands|Linux]]
* [[Linux#Commands|Linux]]


=Usage=
=Numeric Arguments=


==Case Insensitive Search==
All numeric arguments are interpreted as follows:


<pre>
: +n for greater than n
find . -iname ...
: n for exactly n
</pre>
: -n for less than n


==Control Descend Depth==
=Other Arguments=


<pre>
==<tt>-print</tt>==
-maxdepth n
</pre>


It prints the pathname of  the current file to standard output
==<tt>-print0</tt>==
This primary always evaluates to true.  It prints the pathname of the current file to standard output, followed by an ASCII NUL character (character code 0). Useful [[#Iterating_over_find_Results_in_Scripts|when iterating over the result of find]].
=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.
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.


==Time Constraints==
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|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 all files modified less that 2 days ago


<pre>
find . -mtime -2
find . -mtime -2
 
</pre>
=-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|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=
<syntaxhighlight lang='bash'>
find . -exec command {} \;
</syntaxhighlight>
 
<syntaxhighlight lang='bash'>
find mydir -name '*.mp3' -exec sh -c '
    echo "Playing ${1%.mp3}"
    play "$1"
  ' sh {} \;
</syntaxhighlight>
 
=Iterating over <tt>find</tt> Results in Scripts=
 
<br>
<br>
<font color=darkkhaki>TODO: reconcile and merge with [[Bash Listing Files in a Directory and Testing whether Specific Files Exist in Directories]].</font>
<br>
<br>
 
 
<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:
<syntaxhighlight lang='bash'>
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')"
</syntaxhighlight>

Latest revision as of 18:54, 14 August 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

-print0

This primary always evaluates to true. It prints the pathname of the current file to standard output, followed by an ASCII NUL character (character code 0). Useful when iterating over the result of find.

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



TODO: reconcile and merge with Bash Listing Files in a Directory and Testing whether Specific Files Exist in Directories.


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')"