Loading
0x80Lesson 9 of 18

Find files and act on them

Search directory trees by name, type, size and age with find, and feed the results to other commands.

22 min 7-question quiz 2 code exercises
By the end of this lesson you can
  • Search directory trees with find’s tests: -name, -type, -size, -mtime
  • Act on results with -exec and xargs
  • Handle file names with spaces safely using -print0 and xargs -0

Globs only look in one directory. find walks a whole tree and tests every file it meets:

1find . -name "*.log"                 # by name (quote the pattern!)
2find . -iname "readme*"              # case-insensitive name
3find /var/log -type f -size +10M     # regular files bigger than 10 MB
4find . -type d -name cache           # directories called cache
5find . -mtime -1                     # modified in the last 24 hours
6find . -maxdepth 1 -empty            # empty things, without descending
7find . -name "*.tmp" -o -name "*.bak"  # -o means OR
8find . ! -name "*.sh"                # ! means NOT

Quote the pattern: unquoted, the shell would expand *.log against the current directory before find even starts.

find.sh
1cd "$(mktemp -d)"
2mkdir -p station/{deck1,deck2/lab,archive}
3touch station/deck1/engine.log station/deck2/lab/samples.csv
4touch station/deck2/lab/scope.log station/archive/old.log station/readme.txt
5find station -name "*.log" | sort
6echo "--"
7find station -type d | sort
8echo "--"
9find station -name "*.log" -not -path "*/archive/*" | sort
Output
station/archive/old.log
station/deck1/engine.log
station/deck2/lab/scope.log
--
station
station/archive
station/deck1
station/deck2
station/deck2/lab
--
station/deck1/engine.log
station/deck2/lab/scope.log

find lists files in whatever order the filesystem stores them, so pipe to sort when you need a stable order.

Doing something with what you found

Three ways to act on each result:

  • -exec cmd {} \; runs cmd once per file, with {} replaced by the path. The \; (escaped so the shell doesn’t eat it) ends the command.
  • -exec cmd {} + packs as many paths as fit into each run of cmd - much faster for many files.
  • -delete removes what matched. Run the same find without it first!

xargs is the general version: it reads words from stdin and turns them into arguments for a command. find . -name "*.log" | xargs wc -l counts the lines of every log.

xargs.sh
1cd "$(mktemp -d)"
2mkdir notes
3printf 'a\nb\n' > "notes/mission log.txt"
4printf 'c\n' > notes/todo.txt
5find notes -name "*.txt" | sort | xargs cat 2>&1 | head -n 2
6echo "--"
7find notes -name "*.txt" -print0 | xargs -0 cat | wc -l
8find notes -name "*.txt" -exec wc -l {} + | sort
Output
cat: notes/mission: No such file or directory
cat: log.txt: No such file or directory
--
3
1 notes/todo.txt
2 notes/mission log.txt
3 total

Key takeaways

  • find walks a tree, testing -name, -type, -size, -mtime and more.

  • Quote name patterns so the shell doesn’t expand them.

  • -exec ... {} + and xargs run commands on the results.

  • Use -print0 | xargs -0 whenever file names might contain spaces.

Lesson quiz

7 questions · pass with 5 correct · up to 50 XP

Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.

Practice: write Bash scripts

Write a script in the editor and run it for real against sample input. Each run gets a fresh Linux sandbox with Bash 5.2 and the GNU tools on Wandbox, a free public service - so experiment freely, even with rm. Your script and test input are sent there.

Exercise 1

Round up the logs

+25 XP

The starter builds a small station tree. Print the path of every .log file under station, skipping anything in archive, sorted. Then print how many there were.

Expected output:

1station/deck1/engine.log
2station/deck2/lab/scope.log
3station/deck3/reactor.log
43
  • Finds three logs
script.sh
Loading editor…

Your script runs with Bash 5.2 and GNU tools on Wandbox, a free public service, in a fresh sandbox each time. Your script and test input are sent to that service.

Exercise 2

Count every line

+25 XP

The starter writes some notes, one with a space in its name. Print the total number of lines across all .txt files under notes - just the number. Make it safe for spaces in names.

  • Counts six lines
script.sh
Loading editor…

Your script runs with Bash 5.2 and GNU tools on Wandbox, a free public service, in a fresh sandbox each time. Your script and test input are sent to that service.

Questions about this lesson

Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.

Loading posts…

Did you like the lesson? 😆👍
Consider a donation to support our work: