What is the command for getting a filename with any character EXCEPT a few?
Say I do not want the filename to contain the letters q and Q
ls [^qQ] does not work. What would I do?
If you want to use globbing (it's not always a good idea), you can use:
$ ls -d !(*[qQ]*)
or with shopt -s nocaseglob
:
$ shopt -s nocaseglob
$ ls -d !(*q*)
The -d
option so as to not list the content of the matched directories.
For this to work you must have extglob
set, it's probably the case by default. If not, shopt -s extglob
will do.
A better approach would be to use find, as you'll be able to -exec
some stuff on the matched files if you need (rename, grep, edit, etc...), and you'll have a much better control on what you need to match. An example:
$ find . -maxdepth 1 \! -iname '*q*' -type f
This will find all files (-type f
) in current directory (.
) not in subdirectories (-maxdepth 1
) that don't (\!
) have a q or a Q in their name (-iname '*q*'
).
If you have a huge number of files, find is better and faster than Bash's globbing, and won't overflow the maximal number of arguments.
Hope this helps!
If bash extended globbing is enabled, then you can invert matches with !(pattern) e.g. if
$ touch aQq qwerty uiop asdfg bnmq
$
$ ls
aQq asdfg bnmq qwerty uiop
then
$ ls !(*[qQ]*)
asdfg uiop
whereas
$ ls *[qQ]*
aQq bnmq qwerty
You can check the current value of the extglob option using shopt -p extglob
and set it with shopt -s extglob
. Type help shopt
at the bash prompt for more info.
Why not simply
ls | grep -v [qQ]
If instead of single characters you want to exclude file names containing certain strings of charaters you could do so with
ls | grep -v "str1\|str2\|..."
i.e. separating any string with the escaped pipe char |
(which acts as an "OR" logical operator). Remember to enclose it in double quotes to prevent special characters to be misinterpreted.