40

How do I manage to find all files in a directory and subdirectories and run a command on them?

For example,

find . -type f -name "*.txt" 

finds all txt files and:

find . -type f -name "*.txt" | gedit

sends it to gedit, but inside a text file. I want gedit to open all text files.

3 Answers 3

62

You can use the -exec flag to execute a command on each matching file:

$ find ./ -type f -name "*.txt" -exec gedit "{}" \;

Syntax

The syntax is a bit strange (see -exec command ; in the manpages for more):

The string `{}' is replaced by the current file name being processed

You may also want to consider -execdir, which will do the same, but executes the command from the subdirectory containing the matched file (this is generally preferable).

3
  • 1
    Thanks. I see that it works. But what does the end ("{}" \:) means? execute list?
    – xyz
    Mar 14, 2013 at 21:18
  • 4
    The {} stands in for the current file name, and the semicolon is just terminating the command. The backslash and the surrounding quotes are just to prevent shell expansion.
    – David Cain
    Mar 14, 2013 at 21:20
  • I used a similar syntax to trace through a large file hierarch with multiple git repositories to find out if any files had been modified with find . -iname ".git" -execdir git status \; which looks for any directory that contains a hidden file named .git and then performs git status in that directory where the file was found. This finds all of the Git repositories in the file hierarchy and performs a git status on that repository to tell me if anything has changed. Left off the \; the first time and the command failed. Added it to the end and work great. Thanks. Nov 23, 2023 at 18:14
14

find . -type f -name "*.txt" -print0 | xargs -0 gedit

6
  • Thanks. I see that it works. But what does the -print0 | xargs -0 part means?
    – xyz
    Mar 14, 2013 at 21:19
  • 1
    @xyz, you can read about the flags of any UNIX command using the man pages. Try man find or man xargs, then / to search for a given flag. The documentation is quite good, it should answer your questions.
    – David Cain
    Mar 14, 2013 at 21:21
  • 3
    -print0 prints a NULL character after each entry, -0 expects entries to be separated by NULL character. It is the safest way to handle tricky names.
    – Notinlist
    Mar 14, 2013 at 21:22
  • And isn't it a little bit strange that the syntax is not gedit xargs -0 instead of xargs -0 gedit. I see that the former doesn't work, but fail to see why.
    – xyz
    Mar 14, 2013 at 21:32
  • 4
    xargs is preferable to -exec for performance reasons since xargs can "batch up" a number of arguments before passing them to gedit. If one needed to run gedit against each file individually, replace '... -print0 | xargs -0 gedit' with '... -print0 | xargs -0 -i gedit {}' xargs is one of those commands like find and screen that you never know how you got along without a year after you learn about it.
    – arclight
    Apr 22, 2014 at 12:27
3

If the input argument to the command also needs manipulation, use "-I":

find ./ -type f -name "*.ext" -print0 | xargs -0 -I{} mv "{}" "{}.txt"
1
  • Avoid posting answers to old questions that already have well received answers unless you have something substantial and new to add.
    – Toto
    Aug 14, 2022 at 18:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .