I'm new to Unix and trying to show all the files (without directories) in my directory, so I use the command ls -p | grep -v /.

It shows me a list that looks something like this:


But when I use the command ls -p | grep -v / | grep P*, it shows only some of the processes. Why don't all of the processes show?


I realized that I used capital P instead of lower case p. This is a mistake.

  • Process? You mean "files"? – Kusalananda Jul 31 '16 at 10:41
  • Do you have several files named Process...? – JigglyNaga Jul 31 '16 at 10:42
  • It's not really "Process", it's some other names but all start in the same letter and only some show when I use ls -p | grep -v / | grep P* – asaf92 Jul 31 '16 at 10:44
  • What shell are you using? – JigglyNaga Jul 31 '16 at 10:45
  • 1
    In some 30 years of UNIX, this is the first time I saw somebody actually use ls -p. Congratulations, there must be a prize waiting for you somewhere. :) – Satō Katsura Jul 31 '16 at 11:04

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 P.

Use 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.

Just double-quoting P* won't solve this as the regular expression P* also matches filenames such as APPLE and 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 P:

$ find . -type f -maxdepth 1 -name "P*"

This will find all regular files (-type f) in the current directory (.) with names starting with P (-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.

|improve this answer|||||
  • Thanks. can you please explain what this command with these parameters do? – asaf92 Jul 31 '16 at 10:53
  • @StéphaneChazelas I changed -type f to !type d and it says type: Event not found – asaf92 Jul 31 '16 at 10:56
  • @PanthersFan92 ! -type d – Kusalananda Jul 31 '16 at 10:57

The "P*" would be matching something (or not) from your shell before grep sees the parameter. If you quote it, you'll get better results, but bear in mind that grep matches regular expressions rather than globs.

So just a "P" would work. Because it is a regular expression, you do not need the asterisk * to allow the characters following "P" to be matched (grep ignores those by default):

ls -p | grep -v / | grep "P"


ls -p | grep -v / | grep '^P'

Following up on the altered question, to ignore case, use the -i option of grep, e.g.,

ls -p | grep -v / | grep -i '^P'

Further reading:

|improve this answer|||||
  • But i'm only looking for files that start with p, so using grep p will return more results than needed – asaf92 Jul 31 '16 at 10:48
  • 1
    Your question was unclear, but I addressed that in the last line of this answer. By the way, your comment uses p rather than P. If you want to ignore case, you should have made that part of the question. – Thomas Dickey Jul 31 '16 at 10:49

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