2

I would like to change the ownership of all files and directories but exclude some directories:

find -user test ! -path "./dir1/*" ! -path "./dir2/*" -exec chown -R root:root {} \;

The ownership of the excluded directories is still changed?

Regards

MadHatter
  • 78,442
  • 20
  • 178
  • 229
HTF
  • 3,050
  • 14
  • 49
  • 78
  • 1
    You're missing an argument: the directory to start the find in. Since that defaults to `.`, if it happens to be owned by user `test`, it will match, and then you're recursively chowning everything under that anyway. – MadHatter Mar 28 '14 at 12:15

3 Answers3

3

find . \( -path ./dir1 -o -path ./dir2 \) -prune -o -user test -exec chown root:root {} \;

Personally, for performance reasons, I prefer:

find . \( -path ./dir1 -o -path ./dir2 \) -prune -o -user test -print0 | xargs -0 chown root

mlv
  • 154
  • 2
  • You have this backward. This will work *only* on `dir1` and `dir2`. The OP want to work on everything *except* those two. – Sven Mar 28 '14 at 12:33
  • No. Doing -prune means exclude dir1 and dir2. The or (-o) means if you didn't prune them like you did with dir1 and dir2, then do the chown. – mlv Mar 28 '14 at 12:35
  • Yes, you are right. Anyway, this still includes the base dirs in the output and will `chown` them. – Sven Mar 28 '14 at 12:45
  • Yes, it includes . and other directories in . I thought that was asked. – mlv Mar 28 '14 at 12:55
  • What I meant was that `./dir1` and `./dir2` will still be listed by this and such `chown`ed. It's not recursive anymore, but still. – Sven Mar 28 '14 at 13:01
  • It has the added bonus (when you use -print0 and xargs -0) of handling files with spaces in it. – mlv Mar 28 '14 at 13:01
  • Did you try it? I did. It works fine. I did, in a directory, `find . \( -path ./dir1 -o -path ./dir2 \) -prune -o -type d -print` and all the directories where I was printed except dir1 and dir2. – mlv Mar 28 '14 at 13:03
  • Yes, and here it prints the base names. – Sven Mar 28 '14 at 13:06
  • What's your OS? I just tried it on OSX and Ubuntu 13.10 and it works fine. – mlv Mar 28 '14 at 13:08
2

Try this:

find . -user test | grep -v '^./dir1\|^./dir2' 

to check if the list is correct and

find . -user test | grep -v '^./dir1\|^./dir2' | xargs chown root:root

to do the rename.

Sven
  • 97,248
  • 13
  • 177
  • 225
0

On Mac OS X you can use the following version of the command posted by Sven:

find . | grep -v '^./@R*' | tr \\n \\0 | xargs -0 chown root:root