Using grep and ls -a commands Using grep and ls -a commands unix unix

Using grep and ls -a commands


 ls -a /usr | grep '^[prs]'

Would select from the output of ls -a /usr (which is the list of files in /usr delimited by newline characters) the lines that start by either of the p, r or s characters.

That's probably what your teacher is expecting but it's wrong or at least not reliable.

File names can be made of many lines since the newline character is as valid a character as any in a file name on Linux or any unix. So that command doesn't return the files whose name starts with p, q or s, but the lines of the filenames that start with p, q or s. Generally, you can't post-process the output of ls reliably.

-a is to include hidden files, that is files whose name starts with .. Since you only want those that start with p, q or s, that's redundant.

Note that:

ls /usr | grep ^[pqs]

would be even more wrong. First ^ is a special character in a few shells like the Bourne shell, rc, es or zsh -o extendedglob (though OK in bash or other POSIX shells).

Then, in most shells (fish being a notable exception), [pqs] is a globbing operator. That means that ^[qps] is meant to be expanded by the shell to the list of files that match that pattern (relative to the current directory).

So in those shells like bash that don't treat ^ specially, if there is a file called ^p in the current directory, that will become

ls /usr | grep ^p

If there's no matching file, in csh, tcsh, zsh or bash -O failglob, you'll get an error message and the command will be cancelled. In zsh -o extendedglob where ^ is a globbing operator, ^[pqs] would mean any file but p, q or s.


If you're trying to find files, don't use ls. Use the find command.

find /usr -name '[prs]*'

If you don't want to search the entire tree under /usr, do this:

find /usr -maxdepth 1 -name '[prs]*'


The comment of @twalberg is perfect for the options you asked.The echo ignores hidden files, but those will be filtered when you only want files starting with [prs].
When you want hidden files for other filters, a similar solution would be ls -ad /usr/[prs]*, where the -d option suppresses the listing of subdirs.
That solution will also show the full path, this can be suppressed when you go to the dir first. When you want to stay in your current directory, use a subshell for it. I use && for skipping the ls when the /usr dir doesn't exist.

(cd /usr && ls -ad [prs]*)