It is easy to to list all lines that match the pattern, but difficult tolist all lines except those that match the pattern.
We can only use ls or joined with grep to get this goal.
(1) Only using ls
bash:
-----------------------------------------------------------
bash-2.05$ ls
aa.txt ab.txt bb.txt
bash-2.05$ ls [^a]* /* success */
bb.txt
bash-2.05$ ls !(a*) /* fail */
bash: !: event not found
bash-2.05$ ls *^b.txt$ /* fail */
*^b.txt$: No such file or directory
-----------------------------------------------------------
ksh:
-----------------------------------------------------------
$ ls
aa.txt ab.txt bb.txt
$ ls [^a]* /* fail */
aa.txt ab.txt
$ ls !(a*) /* success */
bb.txt
$ ls *^b.txt$ /* fail */
*^b.txt$: No such file or directory
-----------------------------------------------------------
we can see from above that different shell works in different way.
(2) Joined with grep
$ ls
aa.txt ab.txt bb.txt
$ ls|grep -v aa*
ab.txt
bb.txt
$ ls|grep -v aa*|grep -v bb*
ab.txt
$ ls | /usr/xpg4/bin/grep -v -E 'aa.*|bb.*'
ab.txt
$
(3) Comparison of these two solutions
Solution 1 only using ls is fit to some special situation, such as ftp. Because in ftp we can’t use pipe, that is we can’t use solution2.
But solution 1 is shell dependence. And it’s difficult to realize combine condition, such 'aa.*|bb.*'.
Solution 2 is easy to realize combine condition, such as 'aa.*|bb.*'.