Today is going to be a practical tip. If you're managing many Unix systems, sooner or later you come across files with special characters – they can't be deleted with rm command using standard approach and require a bit of trickery to be successfully removed.
Examples of files with special characters
Any language apart from English will probably have special characters in the alphabet, but for the purpose of today's exercise I'll give you more standard examples: files starting with dash (-) and hash (#) characters:
ubuntu$ ls -al -rw-r--r-- 1 greys admin 0 Sep 25 05:50 #try -rw-r--r-- 1 greys admin 0 Sep 25 05:48 -try
Now, if you try to access these files or remove them, you will get errors:
ubuntu$ cat -try cat: invalid option -- r Try `cat --help' for more information. ubuntu$ rm -try rm: invalid option -- t Try `rm ./-try' to remove the file `-try'. Try `rm --help' for more information.
These errors happen because commands treat file names as command line options because they start with dash (-).
With filenames starting with hash (#), you'll get a different kind of error: your Unix shell will treat the rest of a filename (and anything that might follow it) as a comment because hashes are used to do it in shell scripts. That's why your cat command will not show any error but will not finish until you Ctrl+C it:
ubuntu$ cat #try
… and if you try removing such a file, you'll get a complaint from the rm command about missing command line parameters – because of the hash (#) sign, rm command receives no text as a parameter:
ubuntu$ rm #try rm: missing operand Try `rm --help' for more information.
How to remove a file when filename starts with dash (-)
First I'm gonna show you how to make your Unix shell interpret any filename directly instead of trying to analyze it as a set of command line options.
To make command ignore the leading dash (-) in a filename, use the — command line option:
ubuntu$ rm -- -try
As you can see, our file is gone:
ubuntu$ ls -al -rw-r--r-- 1 greys admin 0 Sep 25 05:50 #try
Using backslash to escape special characters in a filename
Another option we have is to use a backslash (\), which will make shell interpreter ignore the special functionality of a character which immediately follows it. To escape the hash (#) our second file has, we should therefore do the following:
ubuntu$ rm \#try
Interesting to know: bash shell has an auto-completion functionality built in. When you type a filename, just press Tab key to make it auto-complete the name for you. Speaking of special characters in particular, quite a few of them are recognized by auto-completion and get escaped automatically.
So, if you start typing:
ubuntu $ rm #t
… and then press Tab, bash will not only auto-complete the name, but escape the leading hash (#):
ubuntu $ rm \#try
There's a few more tricks you can use for escaping special characters, but they're worth a separate post, so stay tuned! Until then, enjoy getting rid of annoying files with special characters in filenames!
Wayne Hammond says
To remove a leading dash from a filename, use the "rename" command like this:
rename – "" *
The first character is what you want to replace, the "" is an empty string (nothing) and the * is the files to process (all of them in the directory). Works really quickly, did about 2500 files in a few seconds!
Gleb Reys says
Thanks for sharing the tip!
Thanks – pesky little bugger !
Gleb Reys says
Boy, was I glad the first time (a few years back) I learned about this! 🙂
1. go to the directory where there are files with "Special Characters" that you want to remove.
2. rm ?*
3. select y or n
Love the tab completion hint! That's what I'm talking about have BASH do my work… go get a soda… or something….
woops I ran this command accidently from my PWD as root… *just kidding* DISCLAIMER: DO NOT BLINDLY RUN THESE COMMANDS
Gleb Reys says
Good point, should not be run unless you're clear about what you're doing