Listing files with grep?
I have a directory that contains the following files:
file1a file1ab file12A2 file1Ab file1abI want to list all files that start with file1 and followed by two letter at most!
The solution I have proposed is as follows:
ls | grep -i file1 [az] {2}But it does not work!
I want to know why? and how to list?
03 Answers
You don't need piping, grep or ls. Just use shell globbing.
In bash, using extglob pattern (should be enabled by default in interactive sessions, if not do shopt -s extglob to set it first):
file1@(|?|??)? matched any single character, @(||) selects any of the patterns separated by |.
If you only meant to match any characters between a-z and A-Z, use use character class [:alpha:] which denotes all alphabetic characters in the current locale:
file1@(|[[:alpha:]]|[[:alpha:]][[:alpha:]])Example:
$ ls -1
file1
file112
file11a
file12A2
file1a
file1ab
file1Ab
file1as
file2
fileadb
$ ls -1 file1@(|[[:alpha:]]|[[:alpha:]][[:alpha:]]))
file1
file1a
file1ab
file1Ab
file1aszsh supports this natively:
file1(|[[:alpha:]]|[[:alpha:]][[:alpha:]])I am answering this portion very reluctantly, upon request from OP.
Any future reader, Don't parse ls, use globbing.
Using ls and grep:
ls | grep -E '^file1[[:alpha:]]{,2}$'Example:
% ls | grep -E '^file1[[:alpha:]]{,2}$'
file1
file1a
file1ab
file1Ab
file1as 13 Whats about find?
find . -maxdepth 1 -regextype posix-egrep -iregex '\./file1[a-z]{,2}.*' 2 find with -regex flag is more appropriate for this sort of job, especially since it's a general rule that output of ls should never be parsed.
However, you've stated that you are looking for files only in one directory ( not descending into subdirectories ), and that you'd specifically want ls and grep. The solution is
\ls | grep -E 'file1[a-z]{2,}' Considering also that you are searching in the current directory, but avoiding parsing ls, here's another solution
for file in * ; do echo "$file" | grep -E 'file1[a-z]{2,}' ;done
./file1ab
./file1abcIn my current directory, I have two files, file1ab and file1abc. In both cases, the result is the following:
xieerqi:$ for file in * ; do echo "$file" | grep -E 'file1[a-z]{2,}' ;done
./file1ab
./file1abc
xieerqi:$ \ls | grep -E 'file1[a-z]{2,}'
file1ab
file1abc