Let's say I have files xinitrc, alphabetsoup, ieat.pie in the current directory. Need a bash script to select only xinitrc and alphabetsoup.


The bash extended glob +([^.]) will match files without any . in their name. It requires that you have not unset shopt extglob (on modern bash installations, it should be set by default). The pattern means:

any number (but at least one) of characters other than .

You can put all the filenames in an array:

NO_EXTENSION=( +([^.]) )

You can print the filenames:

printf "%s\n" +([^.])

Or pass them all to a utility:

ls -- +([^.])

If you want them in variable but not an array, you need to be very sure that no file has whitespace in its name. If you are absolutely certain of this, you can do:

NO_EXTENSION=$(echo +([^.]))

The invocation of echo is necessary in order to get pathname expansion to happen, unlike in the array case. I strongly recommend using arrays for this sort of list, because you don't have to worry about special characters in the filenames.

  • I am trying to set a variable in a bash script. Such that files=*.[nothing].
    – pedram
    Aug 21 '13 at 16:54
  • @multiphrenic: then the above will work.
    – rici
    Aug 21 '13 at 18:09

You can get a list of files without full stop in their names in the working directory with:

find . -maxdepth 1 ! -name "*.*"

You can also have files which are .file under unix, if you want to match those and file, but not file.ext then you can use:

find . -maxdepth 1 ! -name "*.*" -o -name ".*[^.]*"
  • You second one will include dot files that have at least one non-dot character. You need \( -name '.?*' ! -name '.*.*' \). Aug 22 '13 at 21:29

With the extglob option, you can match the complement of a pattern, i.e. the files whose name do not match the pattern. Files with an extensions are the ones that match *.*, so files with no extension in the current directory can be matched this way:

shopt -s extglob
somecommand !(*.*)

Note that dot files (files whose name begins with .) will not be included. If you want to match them as well and treat them as extensionless unless they contain a second ., you can use

shopt -s extglob nullglob
somecommand !(*.*) .!(*.*)


shopt -s dotglob extglob
somecommand !(?*.*)

Maybe you are looking for this:

$ ls | grep -v '\.'


$ ls
alphabetsoup  ieat.pie  xinitrc
$ ls | grep -v '\.'
  • 2
    Never parse ls, it leads to trouble.
    – terdon
    Aug 21 '13 at 22:36
  • 1
    @terdon, if the intent is to store the list in a scalar variable anyway, that's better than the accepted solution that uses echo. Aug 22 '13 at 21:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.