DEV Community

Cover image for A Guide to Searching through the Command Line
Mustafa Hashmani
Mustafa Hashmani

Posted on • Originally published at mustafahashmani.hashnode.dev

A Guide to Searching through the Command Line

locate

  • The locate command performs a search of pathnames across our machine that match a given substring and then prints out any matching names.
  • You have to install this command as it does not comes pre-installed
  • It is nice and speedy because it uses a pre-generated database file rather than searching the entire machine.
  • For example, locate chick will perform a search for all files that contain chick in their name
  • It does not matter which directory you are in as you can locate folders which are in other directories
  • The -i option tells locate to ignore casing
  • The -l or --limit option will limit the number of entries to a number.

find

  • The locate command is nice and easy, but it can only do so much! The find command is far more powerful! Unlike locate, find does not use a database file.
  • By default, find on its own will list every single file and directory nested in our current working directory and also nested in the sub-directories.
  • We can also provide a specific folder. find friends/ would print all the files and directories inside the friends directory (including nested folders)
  • You can also find empty files by running find -empty

    Finding by Type

    • We can tell find to only find by file type: only print files, directories, symbolic links, etc using the -type option.
    • find -type f will limit the search to files
    • find -type d will limit the search to directories

    Finding by Name

    • We can provide a specific pattern for find to use when matching filenames and directories with the -name option. We need to enclose our pattern in quotes.
    • To find all files on our Desktop that end in the .txt extension, we could run find ~/Desktop -name "*.txt"
    • Use the -iname option for a case insensitive search

    Finding by Size

    • We can use the -size option to find files of a specific size. For example, to find all files larger than 1 gigabyte we could run find -size +1G
    • To find all files under 50 megabytes, we could run find -size -50M
    • To find all files that are exactly 20 kilobytes, we could run find -size 20k

    Finding by Time

    • mtime, or modification time, is when a file was last modified AKA when its contents last changed.
    • ctime, or change time, is when a file was last changed. This occurs anytime mtime changes but also when we rename a file, move it, or alter permissions.
    • atime, or access time, is updated when a file is read by an application or a command like cat.
    • We can use the -mtime num option to match files/folders that were last modified num*24 hours ago.
    • find -mmin -20 matches items that were modified LESS than 20 minutes ago.
    • find -mmin +60 matches items that were modified more than 60 minutes ago

      find -mmin -30
      
    • find -amin n will find files that were last accessed n minutes ago. We can specify +n for "greater than n minutes ago" and -n for "less than n minutes ago"

    • find -cmin -20 matches items that were changed LESS than 20 minutes ago.

    • find -cmin +60 matches items that were changed more than 60 minutes ago

    Logical Operators

    • We can also use the -and, -or, and -not operators to create more complex queries.

      find -type -f -not -name "*.html" # any file except .html
      

User-Defined Actions

  • We can provide find with our own action to perform using each matching pathname.
  • The syntax is find -exec command {} ;
  • The {} are a placeholder for the current pathname (each match), and the semicolon is required to indicate the end of the command.
  • To delete every file that starts with contains "broken" in its file name, we could run:

    find -name "*broken*" -exec rm '{}' ';'
    

    Note that we need to wrap the {} and ; in quotes because those characters have special meanings otherwise

xargs

  • When we provide a command via -exec, that command is executed separately for every single element.
  • We can instead use a special command called xargs to build up the input into a bundle that will be provided as an argument list to the next command.

    find -name "*.txt" -exec ls '{}' ';'
    find -name "*.txt" | xargs ls
    
  • This example finds four individual chapter files (chapter1, chapter2, chapter3, and chapter4) and then passes them to the cat command, which then outputs the combined contents to a file called fullbook.txt.

    find -name "chapter[1-4].txt" | xargs cat > fullbook.txt
    
  • xargs reads items from standard input, separated by blanks (spaces or newlines) and then executes a command using those items

  • The mkdir command expects us to pass arguments. It doesn't work with standard input, so this example does NOT make any folders for us

  • We can instead add in the xargs command, which will accept the standard input coming from echo and pass them as arguments to mkdir.

    echo "hello" "world" | mkdir # mkdir: missing operand
    echo "hello" "world" | xargs mkdir
    ls # hello world two folders made
    

Grep

  • The grep command searches for patterns in each file's contents. Grep will print each line that matches a pattern we provide.
  • For example, grep "chicken" animals.txt will print each line from the animals.txt file that contains the pattern "chicken"

    grep PATTERN FILE
    
  • Use the -i option with grep to make the search case insensitive.

  • grep -i "Chapter" book.txt will print all matching lines from the book.txt file that contain the word "chapter" in any casing.

  • Use the -w option to ensure that grep only matches words, rather than fragments located inside of other words.

  • grep -w "cat" book.txt would match cat but not catheter!

  • Use the -r option to perform a recursive search which will include all files under a directory, subdirectories and their files, and so on.

  • grep -r "chicken" will search the current working directory and any nested directories for lines that contain "chicken"

  • The -c option tells grep to print the number of matches instead of printing the actual matches

  • The -o option tells grep to only print out the matches, rather than the entire line containing each match.

  • We can also provide regular expressions to grep by using the -E option

Top comments (0)