I'm writing a command line script to 'unpack' folders with .svg files from downloads. I've copied the required files to a specific directory and now I need to delete all the directories with .svg files in them because they are full of other formats and licences, which I don't need. How do I do this?

2 Answers 2


GNUly, that could be:

LC_ALL=C find . -name '*.svg' -type f -printf '%h\0' |
  LC_ALL=C sort -zu |
  xargs -r0 echo rm -rf

Where find reports the dirname of all .svg regular files, sort -zu removes duplicates, and xargs rm removes them.

That's not terribly efficient in that it keeps looking for .svg files in children of a given directory even after .svg file have been found in it.

Note that if the current directory contains .svg files, rm will refuse to delete it (as a safeguard on rm -rf . to work around a misfeature in some shells where rm -rf .* includes . and .. in the expansion of .*).

You can work around that by replacing . with "$PWD" above.

Remove the echo when you're satisfied it will do what you want.

With the bosh shell, you could do it more efficiently with its builtin find:

has_svg() {
  find "$@" -maxdepth 1 -name '*.svg' -type f -call return 0 \;
  return 1

find . -type d -call 'has_svg "$1"' {} \; -prune -exec echo rm -rf {} +
  • Thanks! I tried the find command before, but I probably did something wrong earlier. It seems to be one of the slightly more confusing ones. Jul 23, 2020 at 7:01

Using GNU find we employ find within find to first look at a dir starting from the lower levels and then check whether that dir comprises atleast one .svg file. We delete such dirs.

$ find . -depth  ! -name . -type d  \
    -exec sh -c '
      for d do
        test "x$(find "$d/." -maxdepth 1 -type f -name "*.svg" -print -quit)" != "x" &&
          set -- "$@" "$d"
      shift "$N"; rm -rf ${1+"$@"}
 ' find-sh {} +
  • Fixed the issue. Thanks. Jul 23, 2020 at 22:37

You must log in to answer this question.

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