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
.
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]*)