find files where group permissions equal user permissions

1

Is it possible to do something like find -perm g=u? I say "like" because -perm mode requires mode to specify all the bits, not just g, and because I can't put u on the right side of the =, like I can with the chmod command:

you can specify exactly one of the letters ugo: the permissions granted
to  the  user  who  owns the file (u), the permissions granted to other
users who are members of the file's  group  (g),  and  the  permissions
granted  to  users  that are in neither of the two preceding categories
(o).

At the moment, I'm doing find | xargs -d \\n ls -lartd | egrep '^.(...)\1 which is just ugly.

Thanks.

Jayen

Posted 2012-06-17T23:33:51.963

Reputation: 443

Answers

2

This is much nicer (produces newline delimited output):

find . -type f -printf '%04m%p\n' | perl -ne 'print substr($_, 4) if /^.(.)\1/'

Or this if any of your filenames might contain newline characters (produces null-byte delimited output):

find . -type f -printf '%04m%p\0' | perl -n0e 'print substr($_, 4) if /^.(.)\1/'

Essentially, the find command produces output like this:

0644./.config/banshee-1/banshee.db
0664./.config/gedit/gedit-print-settings
0664./.config/gedit/gedit-page-setup
0644./.config/gedit/accels

The perl command then filters this output and strips off the file's mode before printing any matching line:

./.config/gedit/gedit-print-settings
./.config/gedit/gedit-page-setup

If you want to include directories, FIFOs, sockets, and device nodes rather than just files, omit the -type f. Then all symbolic links will appear in the list (as they always have mode 0777), so you may want to either exclude them with ! -type l or follow them with -L.

PleaseStand

Posted 2012-06-17T23:33:51.963

Reputation: 4 051

-printf, genius! – Jayen – 2012-06-18T08:47:56.433

1

Try this: (had to edit, neglected to handle filenames with spaces)

find . -type d -or -type f -ls | \
 awk '{ perm=$3; fname=11; if (substr(perm,1,3) == substr(perm,4,3)) { printf "%s",perm; while (fname<=NF) printf " %s",$(fname++); printf "\n"; } }'

Line split at pipe for readability, but functionally just one line

Using find to only show files and directories, which excludes symlinks (always have lrwxrwxrwx perms), sockets and other non-wants.

The awk script parses the output of the find 'ls', compares the substrings corresponding to user and group permissions, if equal, prints the permissions and the filename.

Of course, you could remove the 'perm,' part of the print statement to have only the filenames output, after you've tested it to your satisfaction.

lornix

Posted 2012-06-17T23:33:51.963

Reputation: 9 633

looks good, but i prefer the PleaseStand's answer because it's shorter and I like perl – Jayen – 2012-06-18T08:47:30.960