I would like to remove all files ending with a given set of extensions in a particular directory in a /bin/sh shell. With a /bin/bash I can do it with regex like this :

rm path/(*.pdf|*.png)

but this doesn't seem to work with plain sh. Is it normal ? Is there any kind of regex support?

  • Are you really asking about the Bourne shell (which is not found on many systems these days), and not about POSIX shells such as /bin/sh on Linux, *BSD, OSX, etc.? Aug 18, 2015 at 22:23
  • @Gilles I may be confused... I thought that /bin/sh was a Bourne shell. My question refers to /bin/sh
    – PinkFloyd
    Aug 19, 2015 at 7:03
  • 1
    /bin/sh was the Bourne shell in commercial unices, but never on Linux or *BSD where it's another shell (usually dash or one of the ksh variants these days) which is mostly compatible with the Bourne shell and POSIX-compliant. Aug 19, 2015 at 7:24
  • Note that (*.pdf|*.png) is not a regexp. As a (extended) regex, that would rather be something like ^path/[^/]*\.(pdf|png)$. You can easily see the regexps are not really adapted to do globbing. Aug 19, 2015 at 11:19

3 Answers 3


No, that won't work in a strictly POSIX-compliant shell. Here's the normative reference:


As you can see, definitely no regex, and not even the {a,b} brace notation.


As stated in user3188445's answer this is not POSIX-compliant.

However, if you want to do it anyway, you have to use another tool like find:

find dir/ -maxdepth 1 -type f -regex ".*.pdf\|.*.png" -delete

find searches the dir dir/, not recursively (-maxdepth 1), only file are found (-type f). The regular expression matches .pdf and .png files and -delete remove the files found.


To check what shell you are really using with /bin/sh, call:

/bin/sh whatshell.sh

and fetch the whatshell script from this page:


call e.g. wget http://www.in-ulm.de/~mascheck/various/whatshell/whatshell.sh

Typical output:

$ sh whatshell.sh
SVR4 Bourne shell (SunOS 5 variant)

$ bosh whatshell.sh
SVR4 Bourne shell (SunOS 5 schily variant)

$ bash whatshell.sh
bash 3.2.25(1)-release

$ ksh whatshell.sh 
ksh88 Version (..-)11/16/88i

$ ksh93 whatshell.sh
ksh93 Version M 1993-12-28 s+

POSIX does not require a POSIX shell in /bin/sh. If you like to run a POSIX shell call:

PATH=`getconf PATH` export PATH

note that if this resuls in running bash, the shell is not expected to be POSIX compliant.

  • What do you mean by is not expected to be POSIX compliant? bash aims at POSIX compliance when called as sh. It's even certified on OS/X (where it's built with a stricter compliance mode). Aug 19, 2015 at 11:16
  • POSIX certified unfortunately does not mean POSIX compliant. The problem with Mac OS X seems to be that the POSIX validation scripts do not check everything and thus let bash slip though... bash3.x is not POSIX compliant at all, bash4.x is much better but still has minor problems, I unfortunatly forgot what exactly. The main problem with bash3 is that it does not exit on errors with bash -ce 'cmd' and that it runs commands from bash -ce 'cmd' under job control and thus in a different process group.
    – schily
    Aug 19, 2015 at 11:30
  • BTW: a warning on bash including bash4: rm [A-Z]* will remove all files that start with a letter and not only those with upper case letters. The Bourne Shell, ksh-88 ksh93 and zsh do this as expected.
    – schily
    Aug 19, 2015 at 11:35
  • All shells have POSIX compliance bugs. They are found and fixed as they're found. dash, mksh, yash, ksh93, bash the current Free Software POSIX shells are no different in that regard. If you want one case where bash is compliant and most others are not, try for instance: "$shell" -c 'IFS=£; echo "$*"' sh a b in a UTF-8 locale (only yash and bash compliance there). Aug 19, 2015 at 11:38
  • About [A-Z] That would be in non-POSIX locales, where the behaviour is unspecified. bash's behaviour is allowed by POSIX there. Aug 19, 2015 at 11:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .