Dec 052010

terminalSometimes it happen to find in our file system files with strange names, with that i means files with non-alphanumeric characters or spaces between different words, maybe uploaded by users, or files produced by mistake by someone or some program, and unfortunately is often not trivial to do a mv < file > or rm < file >.

Let’s see how to get rid of these horrors.

Case #1, space-separated file.

Suppose you have:

ls -1

test file.txt

To move or delete the file “test file.txt” use shell auto-completion.
In these simple case just write test< tab > and you should see the name automatically completed to: test file.txt


Case #2, space-separated file.

Suppose you have:

ls -1

test file.txt

it’s a case very similar to the former, but this time you’ll see that auto-completion will fail, because you have 2 file starting with test.
Solution 1 use a double quote: rm "test file.txt" will work (single quote work too)
Solution 2 use a backslash before the space: rm test file.txt

Case #3, file that start with a – or —

Now you have in your directory:

ls -1

test file.txt

If you try to do any command you’ll get something like this:

[email protected]:/tmp/test# rm -file
rm: invalid option -- 'l'

Solution 1: In Ubuntu is suggested directly by the shell:

[email protected]:/tmp/test# rm -file
rm: invalid option -- 'l'
Try `rm ./-file' to remove the file `-file'.

And in fact using as an argument of the commands ./-file solves the problem.

Solution 2: use the — parameter, this is used by many unix program to say “the flag for the command are ended”

So you can use for example:

rm -- -file

And it will work fine.
This logic can be used to many programs like: ls, rm, mv e cp. In general the rule is:

comand options -- '--filename'

Another case in which previous methods do not work

With the former methods you should be able to cover all situations, but in case they were not enought then use the inode of the file.
Now you have:

[email protected]:/tmp/test# ls -1
test file.txt
+Xy +8

Let’s say the bad boy is the last one and that formers methods don’t work, check his inode number with:

[email protected]:/tmp/test# ls -i1
285134 -file
285136 --file
3901 file2.txt
285132 test2.txt
2302 test file.txt
285461 +Xy +8

So 285461 is it’s inode number
Now we can use the find command to delete that inode with:

find . -inum 285461 -exec rm -i {} ;

All commands have been tested on Bash and Zsh shell.

Thanks to: for the last solution.

Popular Posts:

Flattr this!

  4 Responses to “How to handle files with strange names”

  1. Grazieeeee!!!!
    … con il numero di inode son riuscito ad eliminarlo il tignosissimo file vuoto

  2. For this type of advice, you /should/ label it as “A duffers guide”, or something similar. All of your suggestions are overly complicated, or have unnecessary dependencies on possibly-unavailable features.

    #1: Delete the file called “test file.txt”
    A: rm “test file.txt”
    or rm test\ file.txt

    #2: Delete the file called “test file.txt”
    A: as above.

    #3: Delete the file called “-file”
    A: rm ./-file
    or rm /full/path/to/-file

    #4: Delete the file called “\+Xy \+\8”
    A: If this is the literal name (your ls is *not* showing binary values in the name), then
    rm ‘\+Xy \+\8′
    If this is the name with binary values shown as escape sequences (“ls -b” or “ls –escape”)
    rm $’\+Xy \+\8’

    • Lol Lew,
      Thanks for the comment, i wanted to do a simple guide but seem that this time i did an Epic Fail 😉
      Still my favorite methos is to use the — flag in rm.


  3. Thanks for that, I have on the odd occasion I have needed to delete or rename a file with a space in it been able to use filename* using the first part of the file name, but knew that would be a problem when more than 1 file name started the same.

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>