There are many ways of doing this. For example, if you are sure your file names don't contain newlines, you can do:
$ ls | cat -n
1 a.sh
2 b.sh
3 c.sh
4 d.sh
A safer way that can deal with file names containing newlines or any other strange characters:
$ c=0; for file in *; do ((c++)); printf '%s : %s\n' "$c" "$file"; done
1 : a.sh
2 : b.sh
3 : c.sh
4 : d.sh
To see why the latter two are better, create a file name that contains newlines:
$ touch 'a long file name'
$ touch 'another long filename, this one has'$'\n''a newline character!'
Now, compare the output of the two approaches:
$ ls | cat -n
1 a long file name
2 another long filename, this one has
3 a newline character!
4 a.sh
5 b.sh
6 c.sh
7 d.sh
As you can see above, parsing ls (which is generally a bad idea) results in the file name with the newline being treated as two separate files. The correct output is:
$ c=0; for file in *; do ((c++)); printf '%s : %s\n' "$c" "$file"; done
1 : a long file name
2 : another long filename, this one has
a newline character!
3 : a.sh
4 : b.sh
5 : c.sh
6 : d.sh
As @Vikyboss points out in the comments, the shell solution above will set the variable $c which will persist after the loop exits. To avoid that, you could add unset c at the end, or use yet another approach. For example:
$ perl -le 'for(0..$#ARGV){print $_+1 ." : $ARGV[$_]"}' *
1 : a long file name
2 : another long filename, this one has
a newline character!
3 : a.sh
4 : b.sh
5 : c.sh
6 : d.sh
ls -q | grep -n ^should work with all kind of filenames if you don't mind seeing question marks instead of funky chars. By the way, is this homework ?