3

When displaying directories in Linux using ls -ld, I get something like this:

user@shell:~/somedirectory$ ls -ld 
drwxr-xr-x 2014 K-rock users 65536 20011-11-05 11:34
user@shell:~/somedirectory$

How would I find the number of subdirectories and files in the somedirectory using the result above? From what I understand, the number of links corresponds to the number of subdirectories, but what about the number of files? How would I read the result of the ls -ld to find those numbers?

Also, this is an assignment and I have to say the number of files and subdir that are in somedirectory using the result shown above. So I can't really use any other code unfortunately.

  • 2
    Your output does not provide this information. Must this be done with ls? Do you want to know the first level of subdirectories only? How shall symlinks (within / outside the subdirectory; dangling ones) be handled? – Hauke Laging Nov 11 '14 at 20:20
  • unfortunately this is all i am given. its an assignment and im trying to figure out how to find the answer and the answer itself so that i know for the future. – k-Rocker Nov 11 '14 at 20:25
3

Since, you want to decipher from the output that you have got, we will try and simplify things.

ls -ld
drwxr-xr-x 4 root root 4096 Nov 11 14:29 .

Now, ls -ld on a directory gives me the output as above. Now, the number 4 is something that you need to concentrate on. The 4 corresponds to:

  • the entry for that directory in its parent directory;
  • the directory's own entry for .;
  • the .. entries in the 2 sub-directories inside the directory.

To verify this, if I just issue ls I could see that I have couple of more directories. So, this gives an idea of what we could decipher from the output of your case.

drwxr-xr-x 2014 K-rock users 65536 20011-11-05 11:34

There are 2012 sub-directories inside which is why you get 2014 in the output.

As to the number of files, it is not possible to find it out from the output that you have.

To test if my theory is correct, I did the below testing.

ls -la | grep -E '[d]' #Display only directories
drwxr-xr-x 12 root root 4096 Nov 11 14:42 .
drwxr-xr-x  4 root root 4096 Nov 11 14:20 ..
drwxr-xr-x  3 root root 4096 Nov 11 14:45 hello1
drwxr-xr-x  2 root root 4096 Nov 11 14:42 hello2
drwxr-xr-x  2 root root 4096 Nov 11 14:42 hello3
drwxr-xr-x  2 root root 4096 Nov 11 14:42 hello4
drwxr-xr-x  2 root root 4096 Nov 11 14:42 hello5
drwxr-xr-x  2 root root 4096 Nov 11 14:42 hello6
drwxr-xr-x  2 root root 4096 Nov 11 14:42 hello7
drwxr-xr-x  2 root root 4096 Nov 11 14:42 hello8
drwxr-xr-x  2 root root 4096 Nov 11 14:21 hello-subdir
drwxr-xr-x  2 root root 4096 Nov 11 14:29 spaced hello

Now, I issue ls -ld command and the output I get is,

ls -ld
drwxr-xr-x 12 root root 4096 Nov 11 14:42 .

It did not take into consideration the files or subdirectories nested inside the subdirectories of the folder. Basically, the above command says I have 10 directories inside my folder.

P.S.: It is often a bad idea to parse something from ls output as it is not reliable. Use find with -maxdepth instead if you have a chance to use it.

  • The number after the permissions is the number of blocks used by the directory special file. It is not the count of anything in the directory. – Barmar Nov 11 '14 at 20:53
  • @Barmar, I believe it is the number of links and not blocks. But I may as well be wrong which is why I added the P.S – Ramesh Nov 11 '14 at 20:57
  • Oh, right. I was thinking of the output of ls -s. – Barmar Nov 11 '14 at 22:38
  • @Ramesh Your grep -E '[d]' is too greedy. It would be better to anchor it to the beginning of the line like this: ls -la | grep "^d" – Timothy Martin Nov 11 '14 at 23:44
  • @TimothyMartin, I never intend to use it since I wanted to explain the OP on how to decipher his output. However, you are right. But since the OP is mainly concerned on how to decipher the ls -ld output, I wanted to explain him which is why I used the greedy approach. – Ramesh Nov 11 '14 at 23:46
1

If you can use ls, then I assume you can use builtin bash functionality too.

Using pure bash to count all entries in the current directory:

$ num_entries () (       # Define a function to:
> shopt -s nullglob      # expand * to empty string if no files
> shopt -s dotglob       # include .files in * expansion
> a=( * )                # create array containing all entries in current directory
> echo ${#a[@]}          # display length of array (number of directory entries)
> )
$ num_entries            # call function for current directory
467
$ 

Using pure bash to count all subdirectories in the current directory:

$ num_dirs () (
> shopt -s nullglob
> shopt -s dotglob
> a=( */ )               # note the */ glob which selects only directories
> echo ${#a[@]}
> )

I put these in ( ) function bodies so the shopt settings would only have effect within that function and have no other side effects.

0

In a simple case this works:

ls -A1 | wc -l
  • 1
    You don't need the -1 option when piping the output of ls. – Barmar Nov 11 '14 at 20:54
0

You may combine a couple of approaches

  1. Number of files in a directory

    ls -l | grep "^-" | wc -l
    
  2. Walk through subdirectories

    find ./subdirectory -type d
    
  3. put together in one command

     find ./subdirectory -type d | xargs -I{} sh -c "ls -l {} | grep -c '^-'"
    

Will recursively result a count of files restisting in the directories.

Of course there a multiple ways to prettify or enrich the output.

  • 2
    grep ... | wc -l in the case is better substitute by grep -c ... – Costas Nov 11 '14 at 20:38
  • sure, grep -c could be used, but won't change the result – domi27 Nov 11 '14 at 20:40
  • 1
    It may not change the result, but it eliminates the need to spawn another piped data stream into another process. – DopeGhoti Nov 11 '14 at 20:48
  • ack - answer improved – domi27 Nov 11 '14 at 20:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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