I am learning basics of bash and I run into troubles. When I try to list files from dev which end with one or two digits I permanently get "No such file or directory".
ls /dev | grep ^.*[0-9]{1,2}$
ls /dev | grep -E ^.*[0-9]{1,2}$
ls /dev | egrep ^.*[0-9]{1,2}$
ls /dev | grep ^.*\[0-9\]\{1,2\}$
All of those commands end with the same response. What am I doing wrong?
Try this:
find /dev -maxdepth 1 -regex '.*[0-9]'
We are using find here because, in general, one should never parse the output of ls.
find /dev -maxdepth 1 finds all the files in /dev (but we stop it from searching /dev's subdirectories).
-regex '.*[0-9]' limits the output of find to files whose names (excluding any directory) that match the regular expression .*[0-9]. It is not necessary to anchor the regex to match from beginning to end of the file name: this is find's default behavior.
By default, find uses emacs-style regular expressions. GNU find can optionally, using -regextype, use one of four other regex styles: posix-awk, posix-basic, posix-egrep, and posix-extended. See man find for details.
Note that, because . matches numbers among other characters, the regex .*[0-9]{1,2} matches 1 or any number of more numbers at the end. This makes it equivalent to .*[0-9]
As Benjamin mentions in the comments, this is simple enough that a regex is not needed. Using instead a glob:
find /dev -maxdepth 1 -name '*[0-9]'
This will find files whose names whose names have at least one non-digit character and end with one or two but not more digits:
find /dev -maxdepth 1 -regextype posix-egrep -regex '.*[^[:digit:]][[:digit:]]{1,2}'
The following might be good enough if you just want to display the file names on the screen but not parse them as part of a pipeline. This will find files whose names have at least three characters and end with one or two but not more digits:
ls /dev/*[^[:digit:]]?[[:digit:]]
This ls solution does have one hitch: it will reject a file name like a1b2 even though it ends with one digit. Since /dev usually doesn't have that naming style, this is probably not much of a problem.
In the above two approaches, I used [:digit:] because it is unicode-safe. If you are in a locale where that doesn't matter, you can use 0-9 instead, if you prefer:
find /dev -maxdepth 1 -regextype posix-egrep -regex '.*[^0-9][0-9]{1,2}'
Or:
ls /dev/*[^0-9]?[0-9]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With