In your second command, you
grep P*. This will prompt the shell to do filename globbing on
P*, i.e. it will expand
P* to all files starting with the letter
set -x in your shell to see what gets executed (turn tracing off with
set +x). I actually have tracing turned on by default in my own interactive shell sessions just to see what I'm doing.
P* won't solve this as the regular expression
P* also matches filenames such as
file.PP, and actually
hello_world.c and all other filenames as well as
P* also matches filenames with no
Ps in them.
Generally, you shouldn't parse the output of
ls though, so the following would be a better way of getting a list of files (not directories) starting with the letter
$ find . -type f -maxdepth 1 -name "P*"
This will find all regular files (
-type f) in the current directory (
.) with names starting with
-name "P*"). The
-maxdepth 1 option restricts
find to only this directory. It would otherwise recurse down into subdirectories as well.
To do with
find what you're doing with
grep -v /, i.e. removing the directories from the list rather than selecting the regular files:
$ find . ! -type d -maxdepth 1 -name "P*"
This will also find non-regular files, such as sockets etc. In some shells it's necessary to escape or quote the
!, i.e. saying
$ find . "!" -type d -maxdepth 1 -name "P*"
$ find . \! -type d -maxdepth 1 -name "P*"
Note that the quoting of
P* is important so that your shell doesn't expand it.