3

I would like to delete everything in one folder, with the exception of two files:

exec.js
.git

I found this:

rm !(exec.js|.git)

Which works in the CL, but when I try to store in a sh file, and call with bash file.sh, this happens:

test.sh: line 1: syntax error near unexpected token `('
test.sh: line 1: `rm !(exec.js|.git)'

Any ideas why?

  • Can you please explain what you are trying to do? – Rahul Jul 23 '16 at 21:30
  • "I would like to delete everything in one folder, with the exception of two files" – FXux Jul 23 '16 at 21:36
  • On Ubuntu, sh is a symlink to dash - are you sure you are executing the script with bash? How exactly are you running it? – steeldriver Jul 23 '16 at 21:58
3

You need

shopt -s extglob

inside the script.

Your bash configuration presumably turns this on automatically for interactive shells (perhaps because you load the bash-completion package for context-sensitive completion); you need to turn it on manually inside scripts.

Also make sure that your script starts with #!/bin/bash (or a variant like #!/usr/bin/env bash, otherwise it may be executed by a different shell that doesn't support this syntax.

For example, this script will create a few files and then remove all except the two you want to keep:

$ cat x
#!/bin/bash

shopt -s extglob

touch f1 f2 f3 exec.js .git foo bar

echo Before: $(ls -A)

rm !(exec.js|.git)

echo After: $(ls -A)

In execution:

$ bash x
Before: .git bar exec.js f1 f2 f3 foo x
rm: cannot remove '.': Is a directory
rm: cannot remove '..': Is a directory
After: .git exec.js

Note that you get errors with . and ..; you'll have seen those on the command line as well:

$ touch f1 f2 f3 exec.js .git foo bar

$ rm !(exec.js|.git)
rm: cannot remove '.': Is a directory
rm: cannot remove '..': Is a directory
  • 3
    bash doesn't turn it on automatically. It's bash-completion, if you have it installed, that does. – Stéphane Chazelas Jul 23 '16 at 21:19
  • Can you provide an working example? – FXux Jul 23 '16 at 21:38
  • I'm trying to: shopt -s extglob rm !(1.js|test.sh)... Doesn't work, the same problem happens. – FXux Jul 23 '16 at 21:39
  • Example provided. – Stephen Harris Jul 23 '16 at 22:22
1

As a suggestion, you can add

GLOBIGNORE=.:..

after the shopt -s extglob to avoid the rm: cannot remove '.': Is a directory error.

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.