Unable to use grep regex to search for filename containing period

gnugreplsregex

Ubuntu 14.x. Using grep to search for all files linuxtest-client2. This includes multiple file extensions (csr, crt, key). When I grep for the middle portion of the filename, "2.", it also returns lines that contain "2" in addition to "2." when using ls -l with it. This causes results to be returned that have a "2" in the file size, date, and time.

Why are the file sizes being trigger by this grep when there is no period after them?:

root@ip-10-198-0-205:/etc/easy-rsa# ls -ltr keys/ | grep -E '*2.*'
total 228
-rw------- 1 root root 3272 Oct 15 18:28 ca.key
-rw-r--r-- 1 root root 2451 Oct 15 18:28 ca.crt
-rw------- 1 root root 3268 Oct 15 18:31 server.key
-rw-r--r-- 1 root root  769 Oct 15 18:42 dh4096.pem
-rw-r--r-- 1 root root 8244 Oct 19 15:36 02.pem
-rw-r--r-- 1 root root 8250 Oct 19 19:21 03.pem
-rw------- 1 root root 3394 Oct 23 19:48 removemetest.key
-rw-r--r-- 1 root root 1785 Oct 23 19:48 removemetest.csr
-rw-r--r-- 1 root root 8264 Oct 23 19:48 removemetest.crt
-rw-r--r-- 1 root root 8264 Oct 23 19:48 04.pem
-rw------- 1 root root 3394 Oct 23 20:50 revoketest449.key
-rw-r--r-- 1 root root 1789 Oct 23 20:50 revoketest449.csr
-rw-r--r-- 1 root root 8270 Oct 23 20:50 revoketest449.crt
-rw-r--r-- 1 root root 8270 Oct 23 20:50 05.pem
-rw-r--r-- 1 root root 3633 Oct 23 20:50 revoke-test.pem
-rw-r--r-- 1 root root 1182 Oct 23 20:50 crl.pem
-rw------- 1 root root 3394 Oct 23 20:54 linuxtest-client1.key
-rw-r--r-- 1 root root 1793 Oct 23 20:54 linuxtest-client1.csr
-rw-r--r-- 1 root root    3 Oct 23 20:54 serial.old
-rw-r--r-- 1 root root 8287 Oct 23 20:54 linuxtest-client1.crt
-rw-r--r-- 1 root root  909 Oct 23 20:54 index.txt.old
-rw-r--r-- 1 root root   21 Oct 23 20:54 index.txt.attr.old
-rw-r--r-- 1 root root 8287 Oct 23 20:54 06.pem
-rw------- 1 root root 3394 Oct 26 17:57 linuxtest-client2.key
-rw-r--r-- 1 root root 1793 Oct 26 17:57 linuxtest-client2.csr
-rw-r--r-- 1 root root    3 Oct 26 17:57 serial
-rw-r--r-- 1 root root 8287 Oct 26 17:57 linuxtest-client2.crt
-rw-r--r-- 1 root root   21 Oct 26 17:57 index.txt.attr
-rw-r--r-- 1 root root 1058 Oct 26 17:57 index.txt
-rw-r--r-- 1 root root 8287 Oct 26 17:57 07.pem

But if I do not use -l on ls, then it returns the proper results that I am looking for, so clearly my regex is correct:

root@ip-10-198-0-205:/etc/easy-rsa# ls keys/ | grep -E '*2.*'
02.pem
linuxtest-client2.crt
linuxtest-client2.csr
linuxtest-client2.key

Best Answer

Grep treats the pattern as a basic regular expression by default, which means . will match any single character. You can just escape the . to make it mean a literal period.

ls -l | grep "2\."

will give you what you're looking for, or you can tell grep to only search for fixed strings, not regex, like

ls -l | grep -F "2."

Since you give grep the -E flag it will actually try to use extended regex, but then you seem to be using shell wildcards, which don't mean what they do in regex. The * in regex means 0 or more of the previous group or character, and . means any character so .* in regex means 0 or more of any character. So grep -E "*2.*" is really the same as grep 2 which is why it is matching so many extra things in the ls -l version

Of course, you could just let the shell handle it for you with wildcards

ls -l *2.*
Related Topic