0

Please help. I am a student and I found this question online, trying to practice and learn.

I am creating a program that will echo each entry in a given directory. If the entry in the directory is a file, it will echo its size. If the entry is a directory it will echo how many items are in that directory. My program below will echo the files in the given directory. My question is how to echo the size of the files and echo how many items in the directory. My program below

Thank you!

#! /bin/bash
# Files Directory
read -p "Enter a Directory or File: " entry
target="$entry"
let count=0
for f in "$target"/*
do 
echo $(basename $f)
let count=count+1
done
echo "Files in the Directory: $count"
exit 0

1 Answers1

1

Since you're learning, here is some guidance on your questions, as opposed to complete script.

There's more than one way to get the size of a file; on Linux systems, the stat utility is a great choice because you can ask it for the bytes directly:

bytes=$(stat -c %s -- "$f")

another option is the wc utility:

bytes=$(wc -c < "$f")

Note that you want to redirect the file into wc as opposed to the instinctual wc -c "$f", as the latter form will also output the filename, while the former (since it does not know the filename), simply outputs the byte count.

To test whether a given file is a regular file or a directory, the usual test is:

if [ -d "$f" ]
then
  echo It is a directory
else
  echo It is not a directory
fi

For counting the number of (non-hidden) files in a directory, you have a few options:

  • use the POSIX-specified set utility:

    set -- /path/to/dir/*;  echo "$#"
    
  • use an array (since you tagged bash):

    files=( /path/to/dir/* )
    echo "There are ${#files[@]} files in there"
    

These will count the number of "files" (files and directories) in that given directory. The default behavior in most shells is to omit dot-files (e.g. .bashrc) when expanding the * glob; you can adjust that with bash by running shopt -s dotglob or shopt -u dotglob, and check it with shopt dotglob.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255