I am new to Linux and I have an assignment which requires writing a shell script that prints all the names of both files and subdirectories of a directory (given as parameter) and this should also print the number of files with the same name for every file from this directory.

My problem is that I was able to print the names of all files and directories and also to do the second part of the task, but I can't bring them together, which means that my output has two different parts:


a1 1
a2 1
#a1, a2 files and a3 directory

And it should look like this:

a1 1
a2 1

This is the code that I used writing my shell script:

#the first part that prints all the names from the directory
cd $mydir
ls -l $mydir | awk '{print $9}'

#the second part that prints the number of files with the same name for every file
file=$(find $mydir -type f -printf '%f\n' | sort | uniq -c)
echo $file
  • Does the existing answer solve your problem? If so, don't forget to mark one with the checkmark; thank you! If not, let us know what happened.
    – Jeff Schaller
    May 21, 2017 at 11:25

1 Answer 1


In the context of a "learning Linux/shell scripting" assignment, I would suggest something along these lines:


for f in "$mydir"/*
  printf "%s %d\n" "$f" $(find "$mydir" -name "$f" -print 2>/dev/null | wc -l)

Adjustments from your script:

  1. no need to cd to the directory in order to ls it
  2. no need to awk the filename; you could just ls it, but ...
  3. running the ls ... awk separately from the find means you got separated output
  4. no need to specially print the find output if all you're doing is counting it
  5. no need to sort the output if all you're doing is counting it
  6. no need to use uniq if you're trying to catch all
  7. I took the liberty of removing -type f in case your assignment would want you to find directories of the same name
  8. added -name "$f" to have find match only files with matching names
  9. use printf to combine the filename and counts into the same line of output
  10. no need to parse the output of ls in order to get the filename(s); that's what for f in "$mydir"/* -- in particular, the * -- does; it expands to match filenames.

I've also quoted all of your variable usages, in case the user provides a filename such as "this file".

This won't show hidden files in the output; you could add shopt -s dotglob to have the "$mydir"/* expand to match dotfiles (hidden files) as well.

As an advanced caveat, this will mis-count filenames that have newlines in them, provided that the user passes in a newline-containing filename to look for.

  • I must apologize for the delayed response to your comment; your suggestions were a really great help for me and I managed to get my assignment done in time because of this. Thank you! May 21, 2017 at 14:30

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.