1

I'm trying to delete some files and folders from a directory. The command (from here):

rm -rf !(file_i_don't_want_to_remove|other|other_one)

Runs fine in terminal, but if I try to use it inside a script (created using vim, 2 lines):

#!/bin/bash
rm -rf !(one|two)

./file.sh: línea 2: error sintáctico cerca del elemento inesperado `('

Translated:

./file.sh: line 2: syntax error near of unexpected element `('

Why?

PS. I've looked for other questions with the same name but they're all too specific for each script and seem not to be the same problem than mine.

4
  • Just a suggestion why don't you loop through all the files which you want to delete eg--> .txt or .jpg etc and delete them, just a suggestion. Commented Dec 3, 2018 at 13:24
  • 1
    Is the bash in your script as new as the one in your Terminal? You need to also set shopt -s extglob for that I think. Commented Dec 3, 2018 at 13:24
  • @RavinderSingh13 may be recursive, more lines for no advantage IMHO. Commented Dec 3, 2018 at 13:29
  • @MarkSetchell I've no idea at all. I've just found the command, tried it in my terminal and it worked, and then tried to use it in a script. I've never used shopt command nor know what does it do. Going to research a bit. Thanks for the clue. Commented Dec 3, 2018 at 13:31

1 Answer 1

4

You need the extglob extension enabled for this syntax to work:

#!/bin/bash
shopt -s extglob
cd /path/to/dir # See the comment below the answer
rm -rv !(one|two)

PS: Do not use rm -f in a script.

PS: If /path/to/dir is coming from a variable, make sure that is is not empty before using it with cd:

if [ -z "${path_to_delete}" ] ; then
    "path_to_delete is empty! Aborting"
    exit 1
fi
cd "${path_to_delete}"
rm -rv !(one|two)
Sign up to request clarification or add additional context in comments.

4 Comments

And if you do rm -r in a file, make sure you cd to the right directory first! I have been bitten by that in the past. Thank $DIETY for tape backups
Incredibly good point! Also if /path/to/dir comes from a variable, make sure that it is not empty before using it in the rm command.
Maybe better to do [ -z "${path_to_delete}" ] || [ ! -d "${path_to_delete}" ] or just cd "${path_to_delete}" || exit
The ! -d check can be a good idea depending on the situation, but note that cd "" will leave the working directory unchanged and return 0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.