1

I have many files in a directory that begins with parenthesis. They are generated by Dropbox due to conflict. Any combination of escaping does not seem to help:

rm -rf "(*"
rm -rf "\(*"
rm -rf \(*

AS frostschutz mentioned, they do not seem to be ASCII characters. How can I find out if this is the case, and what is the work around?

2

5 Answers 5

5

The shell interprets the commandline with certain rules which you have to consider here:

  • You can escape shell metacharacters with \ so that it behaves like an ordinary character.

  • You can use single or double quotes and inside these most (with double quotes) or all (with single quotes) shell metacharacters lose their special meaning.

  • Quotes don't have to be at word boundaries, so that rm th"is fil"e would be the same as rm "this file".

  • The characters []?* can be used for filename expansion. They may not be quoted or escaped for this purpose.

So possible solutions for your case are rm -rf '('*, rm -rf "("* and rm -rf \(*. I don't know why the last one didn't work in your case. Perhaps there is some whitespace in front of the parenthesis?

With the following line you should be able to see if there are any funny characters in your filenames:

for i in *; do od -c <<< "$i"; done
2
  • 1
    There was a space before the parenthesis. Thanks man. Oct 30, 2013 at 17:48
  • ./ helps in case of a leading - in the filename, so that it isn't interpreted as an option. Oct 30, 2013 at 17:59
1

If you put * inside " or ' it will not expand (it's a literal * only).

But you can put the * outside of ":

rm "("*

However this is identical to the rm \(* which you already posted. So if that does not work, either your files do not begin with the ASCII ( character after all (there are Unicode characters that look very similar), or you're trying this in the wrong location.

1
  • @Forethinker: Utf-8 uses the ASCII-set. It is only for extended glyphs escape sequences are used. E.g. "normal" glyphs like a, b, ,, ., ( etc. are used. There is however glyphs that look similar. E.g. this: is a three byte left white parenthesis.
    – Runium
    Oct 30, 2013 at 17:51
0

Two things you can try:

1) rm -f \\(*

(You don't need -r unless you want to recursively delete directories. Since you said "files" I left it off. rm -rf is a dangerous tool and shouldn't be used if it isn't needed.)

2) rm -i *

This method requires a bit of manual intervention, but since non-alphanumeric characters tend to sort first, the things you want to delete tend to come up first and you can issue a ^C when you've gotten them.

As a note, when experimenting with odd wildcards, try using echo in place of rm first. Especially if using rm -rf. That way you can see what the shell thinks it expands to (if anything) before deleting things. Especially since sometimes this type of file is created by someone hoping you'l do something silly and blow away more files than what you intend to.

0

As others have mentioned the 3rd example you included should've worked. As an alternative you could use find to delete these files as well.

Example

Assuming the following sample data.

$ touch "(afile)"{1..5}
$ ls -l
total 0
-rw-rw-r-- 1 saml saml 0 Oct 30 13:47 (afile)1
-rw-rw-r-- 1 saml saml 0 Oct 30 13:47 (afile)2
-rw-rw-r-- 1 saml saml 0 Oct 30 13:47 (afile)3
-rw-rw-r-- 1 saml saml 0 Oct 30 13:47 (afile)4
-rw-rw-r-- 1 saml saml 0 Oct 30 13:47 (afile)5

Now delete the files using find (assuming you have a GNU version of find):

$ find . -name "(*" -delete
$ ls -l
total 0
$
0

In a situation where I only have to clean up such files once, I would simply list them into a file:

$ ls -1 > delete-list

Next, manually edit delete-list so it only contains the names of files I want to remove. Finally:

$ xargs --delim=\\n rm < delete-list

If the names are well-behaved with regard to whitespace, then you can drop the paranoid --delim option.

You must log in to answer this question.

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