Search for a File
Goal: How to search for a file, by name, across a hierarchy of folders.
Searching for Files:
Let us look at a folder with many subfolders and files.
[]$ cd ~/intro_to_linux
[intro_to_linux]$ ls
clusters data fruits.txt software.csv vegatables.txt workshop_all.txt workshop_me.txtThe ls by default only lists the first level of folders and files.
What does the -R option do?
[intro_to_linux]$ ls -R
.:
clusters data fruits.txt software.csv vegatables.txt workshop_all.txt workshop_me.txt
./clusters:
beartooth.html loren.html teton.html wildiris.html
./data:
2021 2022 2023 dd.tx
./data/2021:
Apr feb Nov README.txt Sep
./data/2021/Apr:
20210403.txt 20210427.txt 20210428.txt
./data/2021/feb:
february_01_2021.tx
./data/2021/Nov:
20211114.txt 20211115.txt 20211116.txt hello.txtSearching for Files: Recursive List Continued
./data/2021/Sep:
20210908.txt 20210921.txt
./data/2022:
Dec February Hello.csv Jul Jun readme.txt
./data/2022/Dec:
20221207.txt 20221220.txt 20221230.txt 20221231.txt 2022_dec_01.txt
./data/2022/February:
20220203.txt 20220223.txt
./data/2022/Jul:
20220720.txt 20220722.txt 20220723.TX
./data/2022/Jun:
20220611.txt 20220615.txt 20220624.txt
./data/2023:
Feb Jan Mar ReadMe.txt
./data/2023/Feb:
20230204.txt 20230217.txt 20230223.txt 20230224.txt
./data/2023/Jan:
20230102.txt 20230108.txt 20230115.txt 20230121.txt texttx
./data/2023/Mar:
20230305.txt 20230311.txt 20230313.txt 20230326.txt 20230327.txt HELLO.txt
./data/dd.tx:Check the manual page:
[]$ man ls
...
-R, --recursive
list subdirectories recursively
...Searching for Files: find
Command | Description |
find | Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
default path is the current directory; default expression is -print
expression may consist of: operators, options, tests, and actions:
...
EXPRESSION
The part of the command line after the list of starting points is the expression. This is a
kind of query specification describing how we match files and what we do
...
TESTS
...
-name pattern
Base of file name (the path with the leading directories removed) matches shell pattern pattern.
...
-iname pattern
Like -name, but the match is case insensitive.
... |
The find command is naturally recursive.
Examples
Find the file named: 20230121.txt
[]$ cd ~/intro_to_linux/
[intro_to_linux]$ find . -name 20230121.txt
./data/2023/Jan/20230121.txt
# Check that this file is within the returned location.
[intro_to_linux]$ ls data/2023/Jan/
20230102.txt 20230108.txt 20230115.txt 20230121.txtFind the file named: 20230120.txt
[intro_to_linux]$ find . -name 20230120.txt
[intro_to_linux]$The command completed since we got back to the prompt and no errors were displayed.
No output means that this file could not be found.
The find command is case-sensitive. Find the file with the exact filename README.txt
[intro_to_linux]$ find . -name README.txt
./data/2021/README.txtUse the alternative -iname option to search for a file name that is case-insensitive:
[intro_to_linux]$ find . -iname README.txt
./data/2021/README.txt
./data/2022/readme.txt
./data/2023/ReadMe.txtExamples
Use wildcards to find all files with the postfix .csv:
Lets look at two versions:
With quotes:
[intro_to_linux]$ find . -name "*.csv"
./software.csv
./data/2022/Hello.csvWithout quotes:
[intro_to_linux]$ find . -iname *.csv
./software.csvUsing or not using quotes across commands is an advanced and confusing subject.
If you do not use quotes, then if you have a file in the current directory ending with .csv, the wildcard is essentially expanded by the shell.
So, if you have a file named say "software.csv" (which we do), the command that gets executed is find . -name software.csv.
This single file is found, and the command stops.
Surrounding the search term with quotes prevents this from happening.
Find any files/folders that contain the string dec. Case-sensitive versus case-insensitive.
[intro_to_linux]$ find . -name "*dec*"
./data/2022/Dec/2022_dec_01.txt
[intro_to_linux]$ find . -iname "*dec*"
./data/2022/Dec
./data/2022/Dec/2022_dec_01.txtFind only folders using the type option and d for only directory.
Question: Are we searching with respect to case-sensitive or insensitive?
[intro_to_linux]$ find . -type d -iname "*dec*"
./data/2022/DecFind only files using the f (for file) value for the type option.
[intro_to_linux]$ find . -type f -iname "*dec*"
./data/2022/Dec/2022_dec_01.txtExercises: Find Files
Questions:
What do we notice about some of the
findcommand options?Find any files that contain the string “
hello”, regardless of case, within their filename.Find any folders or files that contain the string “
feb” regardless of case.Can you list only the folders?
Find any files that have the postfix “
tx” – must be lowercase.
Answers (1, 2)
1. What do we notice about some of the find command options?
That some of the single dash options (
-name) are similar to long-names and not single letters.
2. Find any files that contain the string “hello”, regardless of case, within their filename.
[intro_to_linux]$ find . -name "hello"
[intro_to_linux]$ find . -name "hello.*"
./data/2021/Nov/hello.txt
[intro_to_linux]$ find . -iname "hello.*"
./data/2021/Nov/hello.txt
./data/2022/Hello.csv
./data/2023/Mar/HELLO.txtAnswers (3)
3. Find any folders or files that contain the string “feb” regardless of case.
Can you list only the folders?
[intro_to_linux]$ find . -name feb
./data/2021/feb
[intro_to_linux]$ find . -iname feb
./data/2021/feb
./data/2023/Feb
[intro_to_linux]$ find . -iname "*feb*"
./data/2021/feb
./data/2021/feb/february_01_2021.tx
./data/2022/February
./data/2023/Feb
[intro_to_linux]$ find . -type d -iname "*feb*"
./data/2021/feb
./data/2022/February
./data/2023/FebAnswers (4)
4. Find any files that have the postfix “tx” – must be lowercase.
[intro_to_linux]$ find . -name "tx"
[intro_to_linux]$ find . -name "*tx*"
./data/2021/README.txt
./data/2021/Nov/20211115.txt
./data/2021/Nov/hello.txt
./data/2021/Nov/20211114.txt
…
[intro_to_linux]$ find . -name "*tx"
./data/dd.tx
./data/2021/feb/february_01_2021.tx
./data/2023/Jan/texttx
[intro_to_linux]$ find . -name "*.tx"
./data/dd.tx
./data/2021/feb/february_01_2021.txAnswers (4)
Notice: dd.tx is actually a folder, defined by the ’d’ in the long format list.
[intro_to_linux]$ ls -l data
total 4
drwxrwxr-x 6 <username> <username> 2021
drwxrwxr-x 6 <username> <username> 2022
drwxrwxr-x 5 <username> <username> 2023
drwxrwxr-x 2 <username> <username> dd.tx
[intro_to_linux]$ find . -type f -name "*.tx"
./data/2021/feb/february_01_2021.txIf we (forget and) ignore the case (using iname), we would see:
[intro_to_linux]$ find . -type f -iname "*.tx"
./data/2021/feb/february_01_2021.tx
./data/2022/20220723.TXNotice this has listed a file with a capital a postfix .TX - this is not what we wanted.