Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to chown all files whose filenames begin with ChownFileNames. I've used this command, but it doesnt seem to work:

find . -maxdepth 1 |grep 'ChownFileNames*' -exec chown hadoop:hadoop -- {} . \;

What am I doing wrong?

share|improve this question
up vote 7 down vote accepted
chown hadoop:hadoop ChownFileNames*
share|improve this answer

This should work for what you need:

find . -maxdepth 1 -iname 'ChownFileNames*' -exec chown hadoop:hadoop -- {} . \;
share|improve this answer
it's much better to use \+ instead of \; in such cases. It will start one process per multiple files insted of one process per file, therefore the job will be done much faster on large amount of files. – rush Jun 20 '12 at 13:01

The | (“pipe”) symbol means to pass the output of the command on the left to the command on the right. The command find . -maxdepth 1 lists the files in the current directory (plus . itself). The command grep 'ChownFileNames*' -exec chown hadoop:hadoop -- {} . \; doesn't make any sense: you're passing find options to the grep command.

find itself has a way to match file names, the -name predicate. It takes a shell wildcard pattern as argument.

You could use grep to filter the list, but you'd have to provide a valid command line to grep. To retain only file names matching the shell pattern ChownFileNames*, you would need to use the regular expression /ChownFileNames[^/]$. Then you would have to parse the output of grep to transform the list of matching names into command line arguments. Assuming that you're running Linux and the file names do not contain any newlines, you could use xargs:

find . -maxdepth 1 |
grep '/ChownFileNames[^/]*$' |
xargs -d '\n' chown hadoop:hadoop

It is a lot simpler and more robust to use find's -exec action. Note that you can use -exec … {} + to run the command for a batch of files at once instead of once per file. You can also make find list the current directory.

find . maxdepth 1 \( -name . -o -name 'ChownFileNames*' \) -exec chown hadoop:hadoop {} +

There's usually no point in running find when you're only matching files by name (and not e.g. by date) in the current directory (without traversing subdirectories). Unless there are so many files in the current directory that this makes the command line too long, just use

chown hadoop:hadoop . ChownFileNames*
share|improve this answer

Please take a look at the -name or -iname options in find(1)

share|improve this answer
And , especially, -exec option :) – Sergei Lomakov Jun 20 '12 at 11:32

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.