What command lists all files beginning with "a" and having 1 or 2 digits that follow? (The output might display a0, a1, a2, a3, a00, a01, a99,... but not a333, not b12, not art53,...)
2 Answers
In the zsh
shell,
setopt EXTENDED_GLOB
printf '%s\n' a[[:digit:]](#c1,2)(.)
The pattern a[[:digit:]](#c1,2)(.)
would match any regular file whose name starts with an a
followed by one or two digits. The (.)
at the end makes sure we only get names of regular files, while [[:digit:]](#c1,2)
matches one or two digits.
In sh
or bash
etc.,
printf '%s\n' a[[:digit:]] a[[:digit:]][[:digit:]]
This would list all names that start with an a
and then has either one or two digits ofter that (we use one pattern for names with one digit, and another for names with two digits). It is not certain that you'd only get names of regular files though (you may also get names of directories etc.), and if one or the other pattern (or both) does not match any name, the pattern will remain unexpanded (use shopt -s nullglob
in bash
to make the non-matching patterns be removed instead).
To weed out any non-regular file, use a loop:
for name in a[[:digit:]] a[[:digit:]][[:digit:]]; do
if [ -f "$name" ]; then
printf '%s\n' "$name"
fi
done
Here, we apply an explicit -f
test to each name. This test will be true if the name refers to a regular file (or to a symbolic link to a regular file). If the test is true, we print the name.
-
I am using linux and the command you said didn't seem to work, I am not sure where did i make mistake. Sep 7, 2019 at 16:43
-
@AhsanQureshi I show three commands. The first one is for the
zsh
shell, and the other two are forsh
andbash
and similar shells. The last two commands are doing slightly different things, depending on how you want to interpret the word "file", and they will also behave differently if the patterns do not match. I have described this in the text.– Kusalananda ♦Sep 7, 2019 at 16:45 -
[aqureshi@cmsy255 labs]$ a[[:digit:]](#c1,2)(.) -bash: syntax error near unexpected token `newline' Sep 7, 2019 at 16:46
-
is there any easier method to do it ? e.x is there any ls command that can do this ? Sep 7, 2019 at 16:47
-
1@AhsanQureshi Good! If this solves your issue, please consider "accepting" the answer. This is the best way to show gratitude on this site. Accepting an answer not only marks the question as resolved, but also signals to future readers that the accepted answer actually solved the issue. More information about this is available here: unix.stackexchange.com/help/someone-answers– Kusalananda ♦Sep 7, 2019 at 16:55
A more general solution, and one not dependent on which shell you're using, might be something like
Helios:t larry$ ls -1
a0
a10
a100
ax
axe
b4
Helios:t larry$ find . -mindepth 1 -maxdepth 1 -type f -regextype egrep -regex '\./a[[:digit:]]{,2}'
./a10
./a0
But that spawns an additional process.