29

Using the tcsh shell on Free BSD, is there a way to recursively list all files and directories including the owner, group and relative path to the file?

ls -alR comes close, but it does not show the relative path in front of every file, it shows the path at the top of a grouping i.e.

owner% ls -alR
total 0
drwxr-xr-x   3 owner  group  102 Feb  1 10:50 .
drwx------+ 27 owner  group  918 Feb  1 10:49 ..
drwxr-xr-x   5 owner  group  170 Feb  1 10:50 subfolder

./subfolder:
total 16
drwxr-xr-x  5 owner  group   170 Feb  1 10:50 .
drwxr-xr-x  3 owner  group   102 Feb  1 10:50 ..
-rw-r--r--  1 owner  group     0 Feb  1 10:50 file1
-rw-r--r--  1 owner  group     0 Feb  1 10:50 file2

What I would like is output like:

owner group ./relative/path/to/file

The accepted answer to this question shows the relative path to a file, but does not show the owner and group.

Community
  • 1
  • 1
Ben
  • 1,441
  • 4
  • 18
  • 20

8 Answers8

25

How about this:

find . -exec ls -dl \{\} \; | awk '{print $3, $4, $9}'
James Brady
  • 27,032
  • 8
  • 51
  • 59
  • It looks like this fails if there are any spaces in the path because awk will create another field. There any way to print from $9 to the end of the line? – Ben Feb 02 '09 at 16:42
  • Right you are! You *could* read the ls output into a function, shift your way though the arguments and use $@ to read "the rest of the line", but honestly, it's getting messy enough that I'd just write a little Python utility and do it The Right Way instead.. – James Brady Feb 02 '09 at 17:11
  • Or try one of the Perl solutions suggested by slim or Chris. – James Brady Feb 02 '09 at 17:32
  • Spaces in the path? I thought that this question was tagged "linux" – Bruno9779 Nov 18 '13 at 12:49
  • @Bruno9779 Spaces in the path are very much allowed in Linux -- try it -- `touch 'my file with spaces'`. Some people discourage it because it's easy to write shell scripts that choke on them -- but you can't prevent apps and users from creating filenames with spaces. – slim Feb 10 '16 at 10:09
21

Use tree. Few linux distributions install it by default (in these dark days of only GUIs :-), but it's always available in the standard repositories. It should be available for *BSD also, see http://mama.indstate.edu/users/ice/tree/

Use:

tree -p -u -g -f -i

or

tree -p -u -g -f

or check the man page for many other useful arguments.

Davide
  • 17,098
  • 11
  • 52
  • 68
20

Works in Linux Debian:

find $PWD -type f     
Аз_10000
  • 201
  • 2
  • 2
10

find comes close:

find . -printf "%u %g %p\n"

There is also "%P", which removes the prefix from the filename, if you want the paths to be relative to the specified directory.

Note that this is GNU find, I don't know if the BSD find also supports -printf.

Torsten Marek
  • 83,780
  • 21
  • 91
  • 98
8

You've already got an answer that works, but for reference you should be able to do this on the BSDs (I've tested it on a mac) :

find . -ls
Andrew
  • 2,943
  • 18
  • 23
4

If you fancy using Perl don't use it as a wrapper around shell commands. Doing it in native Perl is faster, more portable, and more resilient. Plus it avoids ad-hoc regexes.

use File::Find;
use File::stat;

find (\&myList, ".");

sub myList {
   my $st = lstat($_) or die "No $file: $!";

   print  getgrnam($st->gid), " ", 
          getpwuid($st->uid), " ", 
          $File::Find::name, "\n";
}
slim
  • 40,215
  • 13
  • 94
  • 127
1

Simple way I found was this:

ls -lthr /path_to_directory/*

" * " - represents levels.

Ajiths-MBP:test ajith$ ls -lthr *
test2:
total 0
-rw-r--r--  1 ajith  staff     0B Oct 17 18:22 test2.txt

test3:
total 0
-rw-r--r--  1 ajith  staff     0B Oct 17 18:22 test3.txt

test1:
total 0
-rw-r--r--  1 ajith  staff     0B Oct 17 18:21 test1.txt
drwxr-xr-x  3 ajith  staff    96B Oct 17 18:22 test1_sub_dir


Ajiths-MBP:test ajith$ ls -lthr */*
-rw-r--r--  1 ajith  staff     0B Oct 17 18:21 test1/test1.txt
-rw-r--r--  1 ajith  staff     0B Oct 17 18:22 test2/test2.txt
-rw-r--r--  1 ajith  staff     0B Oct 17 18:22 test3/test3.txt

test1/test1_sub_dir:
total 0
-rw-r--r--  1 ajith  staff     0B Oct 17 18:22 test1_sub_file.txt
Ajith H
  • 11
  • 1
-4

Use a shell script. Or a Perl script. Example Perl script (because it's easier for me to do):

#!/usr/bin/perl
use strict;
use warnings;
foreach(`find . -name \*`) {
  chomp;
  my $ls = `ls -l $_`;
  # an incomprehensible string of characters because it's Perl
  my($owner, $group) = /\S+\s+\S+\s+(\S+)\s+(\S)+/;
  printf("%-10s %-10s %s\n", $owner, $group, $_);
}

Perhaps a bit more verbose than the other answers, but should do the trick, and should save you having to remember what to type. (Code untested.)

Chris Lutz
  • 73,191
  • 16
  • 130
  • 183