Shell, explained

find . -name "*.log" | xargs rm, explained

find . -name "*.log" | xargs rm

find lists every .log file below the current folder, one path per line. xargs reads those lines and runs rm with all of them as its arguments, so every file found is deleted. The quotes around *.log matter: they let find, not the shell, do the matching.

Lines become arguments

xargs collects the three paths and runs one rm with all of them. rm prints nothing when it succeeds.

$

Tap a part of the command to find it below

$ find . -name "*.log"
./app.log
./old/cron.log
./old/debug.log
|

3 lines become arguments for rm

$ xargs rm
runsrm./app.log./old/cron.log./old/debug.log
Tap any part of the command to see what it does

Without the quotes, the shell gets there first

app.log is in the current folder, so the shell turns *.log into app.log before find starts. find then only finds files named exactly app.log.

$

Tap a word to follow it

FOLDERapp.logold
*Globs4 words
find.-nameapp.log
*.log→app.log

find never sees the pattern: ./old/cron.log and ./old/debug.log are missed.

find receives 3 arguments

1.2-name3app.log
Tap any part of the command to see what it does

Part by part

find .
Searches the current folder and everything below it.
-name "*.log"
Matches names ending in .log. The quotes pass the * to find instead of letting the shell expand it.
|
Sends the list of paths, one per line, into xargs.
xargs
Reads lines from its input and runs a command with them as arguments.
rm
The command xargs runs: it deletes the files it is given.

Common mistakes

File names with spaces

xargs splits on spaces, so ./my app.log becomes ./my and app.log. Use find . -name "*.log" -print0 | xargs -0 rm, which separates names with a null character instead.

Deleting before looking

Run the same command with echo first (… | xargs echo rm) to see exactly what would be deleted.

Try it

$ find . -name "*.log"

Preview the list first.

$ find . -name "*.log" -print0 | xargs -0 rm

Safe with spaces in names.

$ find . -name "*.log" -delete

Let find delete them itself.

Questions

Why not rm $(find . -name "*.log")?

It has the same problem with spaces, and with thousands of files it can exceed the maximum command length. xargs splits a long list into several rm runs for you.

Is find -delete better?

For plain deletion, yes: there is no pipe, and spaces and odd characters are no problem. xargs is the general tool for running any command on a list.

What does the . after find mean?

It is the folder to search: . means the current one. find /var/log -name "*.log" searches somewhere else.

Terminaster

Ask about any command and get a picture like this one.

The Terminaster tutor draws these visuals for your own questions, then turns what you learned into spaced-repetition cards so it sticks.