Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

grep No such file or directory

Tags:

bash

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?

like image 518
cAMPy Avatar asked Dec 13 '25 08:12

cAMPy


1 Answers

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]

Simplification:

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]'

Rejecting files whose names end in three or more digits

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]
like image 165
John1024 Avatar answered Dec 14 '25 20:12

John1024