Linux command tips : find

find

Introduction

The find command is used to … find stuff on your computer. It may be seen as a command using “logicals blocks” to specify search criteria , each time a “logical block” is verified (or true) the next one is evaluated, when all the logical blocks are verified and true the result(s) is printed, this is the default behavior. This can be changed by various command line options.

 

 

 

 

1) Find syntaxes & options

1.1 basic find syntax

  • find a file using which name matches <pattern>, case sensitive from current dir
    find -name "pattern"
  • find a file using which name matches <pattern>, case insensitive from current dir
    find -iname "pattern"

 

1.2 find files within a single filesystem

  • search for a file/dir ONLY within the searched filesystem (defined by <path>) using “-xdev” primary  or the equivalent option “-x
    find <path> -xdev "pattern"

    Note : <code>-xdev</code> is not an option, it is a primary which implies that it should appears after path names – contrary to the equivalent option <code>-x</code>must be placed before the path.

 

1.3 find files older or newer than N days

  • Find files older than Ndays
    find -mtime +N
    • example
      bash-3.2$ ls -l
      total 16
      -rwxrwxrwx 1 user GROUP 189 jun 16  2011 PfConfig.txt
      -rwxrwxrwx 1 user GROUP 176 jun 16  2011 StopCle.bash
      bash-3.2$ find /data/user/scripts_tests/ -mtime +1
      /data/user/scripts_tests/StopCle.bash
      /data/user/scripts_tests/PfConfig.txt
      bash-3.2$ find /data/user/scripts_tests/ -mtime -1
      bash-3.2$
      bash-3.2$ touch newer_file.txt
      bash-3.2$ls -l
      total 16
      -rw-r--r-- 1 user GROUP   0 avr 18 11:39 newer_file.txt
      -rwxrwxrwx 1 user GROUP 189 jun 16  2011 PfConfig.txt
      -rwxrwxrwx 1 user GROUP 176 jun 16  2011 StopCle.bash
      bash-3.2$find /data/user/scripts_tests/ -mtime -1
      /data/user/scripts_tests/
      /data/user/scripts_tests/newer_file.txt

 

1.4 find files older or newer than a given file

  • To find files newer than <file>
    find -newer <file>
    • example
      bash-3.2$ ll -ltr
      total 25
      -rwxrwxrwx.  1 user group 10989156 19 mars   2011 AngelBubbled.mp4
      drwxr-xr-x.  2 user group     4096 12 janv. 00:01 Videos
      -rw-rwSr--   1 user group        0 12 févr. 22:24 base_file.txt
      -rw-rw-r--   1 user group     148  2 mars  23:53 test_nfs@fedora_14.txt
      -rwxrwxrwx   1 user group 26047587 31 mars  22:38 result.xml
      
      bash-3.2$ find -maxdepth 1 -newer base_file.txt
      ./result.xml
      ./test_nfs@fedora_14.txt
  • To find files older than <file>
    This is done by negating the -neweroption

    • example
      bash-3.2$ find -maxdepth 1 -not -newer base_file.txt
      ./Videos
      ./AngelBubbled.mp4

 

1.5 Negate a search expression or a pattern

  • find a file which name doesNOT match <pattern>, using the “-not” option or the “!” operator
    find [-not|!] iname "pattern"
    • examples
      bash-3.2$ find /var/log/vmware/ -name "*.log"
      /var/log/vmware/hostd-7.log
      /var/log/vmware/hostd-1.log

      Now with the negation operator “!”

      bash-3.2$ find /var/log/vmware/ ! -name "*.log"
      /var/log/vmware/
      /var/log/vmware/webAccess

      The equivalent using the “-not” option

      bash-3.2$ find /var/log/vmware/ -not -name "*.log"
      /var/log/vmware/
      /var/log/vmware/webAccess

    Note : The negation -not can be applied to any expression / option / primary.

 

1.6 Apply a command to search result(s)

  • find a file matching a <pattern>, case insensitive from current dir and apply a <command> to the matching file
    find -iname "pattern" -exec <command> {} \;
    • example
      bash-3.2$ find /var/log/vmware/ ! -name "*.log" -exec echo find has found : {} \;
      find has found : /var/log/vmware/
      find has found : /var/log/vmware/webAccess
      find has found : /var/log/vmware/webAccess/work
  • Multiple -exec bloc are possible, and useful. In the following example we apply the <command-1> first and then the <command-2> to the matching files…
    find -iname "pattern" -exec <command-1> {} \; -exec <command-2> {} \;
    • example
      bash-3.2$ find /var/log/vmware/ ! -name "*.log" -exec echo "#find has found : {}" \; -exec echo "##deleting  {}..." \; -exec echo \;
      #find has found : /var/log/vmware/
      ##deleting /var/log/vmware/...
      
      #find has found : /var/log/vmware/webAccess
      ##deleting /var/log/vmware/webAccess...
      
      #find has found : /var/log/vmware/webAccess/work
      ##deleting /var/log/vmware/webAccess/work...

    Note : The -exec option will apply the <command> to the files matching <pattern> represented here by the double brace ({}) the line must be ended by the backslash followed by semicolon (\;)

 

1.7 Format find output to match the ls output

  • use “ls” style to print find command results
    [pbe@station33 17695]$ find 192.168.3.93/ -name "test.log" -ls
    55853096   32 -rwxrwxrwx   1 10013    TOP      32385 avr 13 07:33 192.168.3.93/test.log
    62881844   32 -rwxrwxrwx   1 10013    TOP      29810 avr 13 07:32 192.168.3.93/test.log
    62881849  744 -rwxrwxrwx   1 1011     TOP     756595 avr 13 07:38 192.168.3.93/test.log

 

1.8 Use OR operator to build more complex search pattern(s)

  • use the find “or” operator and the command grouping (AKA subshell) to find files matching one <pattern> or <another_pattern>
    find . \( -name "<pattern>" -o -name "<another_pattern>" \)
    • example
      bash-3.2$ find /var/log/ \( -name "messages*" -o -name "yum.log*" \)
      /var/log/yum.log.1
      /var/log/messages.1
      /var/log/messages.2

 

1.9 find files using regular expressions

  • Using the -regex or -iregex (case insensitive) will give even more power to the find command, please note that the default regex set is emacs regex, you may change this using the regextype option (supported regex :
    Note : you may pay attention to the fact that the pattern search is performed against the whole path, not only on the filename (you may need to use “<code>.*<pattern>.*</code>”, please check the “About regular expressions (Basic & Extended)” page for more infos and the following examples)

    find <path> -regex "<pattern>"
    • examples
      bash-3.2$ ls message*
      messages  messages.1  messages.2  messages.3  messages.4
      bash-3.2$ find . -regex '*messages*' # this will not return anything
      bash-3.2$ find . -regex '.*messages.*' # this will gives the messages file and dir
      ./messages.1
      ./messages.2
      ./messages
      ./messages.3
      ./messages.4

 

1.10 exclude a chosen path from the search

Let’s say we want to search for the any cbb files from the current directory, except in the nv5/Ris dir, here is how I would do this (there is some other way using the -prune option + -print option but the following looks like the best to me)

find . -type f -name "*.cbb" -not -path "./nv5/Ris/*"



More “Linux command tips” posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site supports SyntaxHighlighter via WP SyntaxHighlighter. It can highlight your code.
How to highlight your code: Paste your code in the comment form, select it and then click the language link button below. This will wrap your code in a <pre> tag and format it when submitted.