I tried ls /etc/[ac]*
but it shows directories starting with a or c, and their entire contents, not the files starting with "a" or "c".
7 Answers
To avoid listing the contents of directories, you can:
ls -d /etc/[ac]*
That will list the directory names along with ordinary file names starting with a
or c
.
For completeness, a solution not involving find
might be:
ls -ld /etc/[ac]* | grep ^- | tr -s ' ' | cut -d' ' -f9
-
My initial reading of the question also made
ls -d
seem appropriate, but it seems that the original question specifies that no directories should be listed, regardless of expansion or non-expansion. May 22, 2014 at 3:03 -
1
ls -ld /etc/[ac]* | grep ^- | tr -s ' ' | cut -d' ' -f9
don't parsels
. May 22, 2014 at 3:16 -
1@AvinashRaj: Well, the relevance of that advice depends on whether one needs this solution to work once, or forever. If only once, then parsing
ls
is fair game in my opinion. May 22, 2014 at 3:18 -
3He does have a point. While names in
/etc
are very likely to be sane, a simple space will break thels
approach since the field numbers will change. +1 forls -ld
though.– terdon ♦May 22, 2014 at 3:42 -
1You also need to fix the locale (
LC_ALL=C
), date is not guaranteed to have 3 fields in other locales. May 23, 2014 at 14:01
Recursively:
find /etc -type f -name '[ac]*'
If you require non-recursion, you can do this portably:
find /etc/. ! -name . -prune -type f -name '[ac]*'
Or this, non-portably (GNU or a recent BSD find):
find /etc -type f -maxdepth 1 -name '[ac]*'
If you want to do this case insensitively, use -iname
instead of -name
.
-
1Note that
-type f
is for regular files. If instead you need non-directory files, replace with! -type d
(or! -xtype d
with GNUfind
if you also want to exclude symlinks to directories). May 23, 2014 at 13:47
If you want both directorys (not directory's contents) and files, you can use printf
bultin:
printf "%s\n" [ac]*
Example:
$ printf "%s\n" [te]*
examples.desktop
teamviewer_linux.deb
test.php
test.txt
With zsh
:
print -rl /etc/[ac]*(.)
Would list the regular files (as in -type f
in find
) listed in /etc
whose name starts with a
or c
. The (xxx)
part at the end of a glob is a zsh-specific feature called globbing qualifier. .
as a globbing qualifier means regular file.
If the glob doesn't match, zsh
will abort the command. Note that in other Bourne-like shells, if the glob doesn't match, the pattern expands to itself, so ls -d /etc/[ac]*
could incorrectly list a file called /etc/[ac]*
if there's no file starting with a
or c
in /etc
.
print -rl /etc/[ac]*(^/)
would list the files that are not of type directory and
print -rl /etc/[ac]*(-^/)
would list the files that are not of type directory after resolving symlinks.
You may try this command also,
for file in /etc/[ac]*; do echo $file; done | xargs file | awk -v FS=" +" '$2~/directory/ {next;} {print $1}' | sed 's|\/etc\/||g;s/://g'
Non-recursive without find
:
ls -pd /etc/[ac]* | grep -v '/$'
the -p
adds a /
at the end for directories, which the grep
filters out. Of course doesn't work for filenames which contain special characters like newlines.
For display files starting with a:
ls etc | grep ^a
For displaying files starting with c:
ls etc | grep ^c
-
1
ls -d /etc/[ac]*
you would not get the contents of matching directories, but would still see the directory names. It is unclear whether this is what you want or if you would want to avoid even listing the directory names.