I'm looking to recursively look through directories to find files NOT owned by a particular user and I am not sure how to write this.
Asked
Active
Viewed 1.2e+01k times
5 Answers
334
The find(1) utility has primaries that can be negated ("reversed") using the "!" operator. On the prompt one must however escape the negation with a backslash as it is a shell metacharacter. Result:
find . \! -user foo -print

Mel
- 6,077
- 1
- 15
- 12
-
11escaping the `!` seems to be optional – doub1ejack Jan 23 '14 at 15:17
-
piping the output to `xargs ls -al` can provide more info than the `-print` flag – doub1ejack Jan 23 '14 at 15:18
-
2piping the output to `xargs -I{} -P3 -- ${cmdhere} {}` can have ${cmdhere} operate on each file in parallel. cmdhere ::= standard unix utils; standard unix utils ::= chmod, chown, stat, ls, ... – Dwight Spencer Mar 04 '14 at 07:12
-
1@sorin do you mean the `find . ...` or piping to `xargs` the first or second way? – Kev Jul 16 '14 at 16:55
-
5find has the -exec flag -> `find . ! -user foo -exec chown
: – pastephens Feb 12 '15 at 15:06{} \;` -
xargs can provide a significant performance boost .v. -exec, since chown can take a list of many files to chown on the same command like, saving the cost of many execs. – Funcan Apr 20 '16 at 10:49
-
1how to add owner info as output? – Duc Tran Aug 05 '16 at 17:01
-
I used `-not` to avoid escaping the `!` but apparently it isn't POSIX compliant. From the man page: `-not expr Same as ! expr, but not POSIX compliant.`. – marczych Oct 07 '16 at 22:20
-
@Silentbang did you ever figure that out? i would like to know as well – Anthony Aug 30 '17 at 16:42
-
1@Anthony Use printf option to get it along with file name: `find . \! -user foo -printf '%p - %u\n'`. Actually I just found out by reading the 'find' command manual as you reminded me. – Duc Tran Aug 31 '17 at 17:12
-
1thanks! And @Sorin, it does work recursively for me (centos 7 : find /path \! -user myUser) – tisc0 Feb 17 '18 at 22:24
-
5@sorin: The exclamation point must be escaped if Bash history is active (`set -H`) which is usually on by default. – Dennis Williamson Jul 11 '18 at 20:54
46
Looking for files NOT owned by someone
Others have answered the question "NOT owned by a particular user" in the body. Here's one that answers the titular question but has not been provided:
$ find / -nouser
You can use it like so:
$ sudo find /var/www -nouser -exec chown root:apache {} \;
And a related one:
$ find / -nogroup

jww
- 97,681
- 90
- 411
- 885
-
9I'll give you a vote for the technicality, but people would generally say "not owned by anyone" if they meant what you were interpreting. – Shibumi May 21 '18 at 13:26
-
3@Shibumi - Yeah, sounds about right for those splitting hairs. The problem I faced was, I needed to find files literally not owned by any user. It surfaced after a web server refresh and migration. Some user/group ids changed so I needed to script a chown. – jww Jan 03 '19 at 23:08
10
-user
finds by user or user ID, and !
inverts the predicate. So, ! -user ...
.

Ignacio Vazquez-Abrams
- 776,304
- 153
- 1,341
- 1,358
-
5Downvoted because it doesn't add anything to the accepted answer, and it masks other possible answers (such as the zsh glob pattern below). – Ulysse BN Oct 14 '19 at 09:16
10
You can use this:
find <dir> ! -user <username>

CrayonViolent
- 32,111
- 5
- 56
- 79
-
6Downvoted because it doesn't add anything to the accepted answer, and it masks other possible answers (such as the zsh glob pattern below). – Ulysse BN Oct 14 '19 at 09:16
-
1This answer was given 3 minutes after the accepted answer. People deserve credit for giving answers and they are not psychic. – Dino Dini May 28 '23 at 15:32
6
Using z-shell (zsh) you can use
ls -laR *(^U)
or
ls -la **/*(^U)
to search for all files recursively not owned by you.

A.B.
- 460
- 5
- 18
-
It is true that the command above will not list dot files, even with the `-a` flag because of the wildcard expansion. To catch dot files use the zsh `dotglob` option: `setopt dotglob`. In one line: `(setopt dotglob; ls **/*(^U) )`. The parentheses are to run in a subshell so that you don't have to run `setopt nodotglob` after you've finished. – Zorawar Mar 09 '18 at 01:31
-
@Zorawar You can also add `D` to the parenthesis: `ls **/*(D^U)`. – Marc Cornellà Dec 22 '20 at 19:55
-
@MarcCornellà You're right; I did not know that. Thank you. That's a much better option than having to use setopt if it will be a one-time usage. – Zorawar Dec 23 '20 at 22:37