How do I remove a file with funny characters in the filename ?

How do I remove a file with funny characters in the filename ?

If the 'funny character' is a '/', skip to the last part of this
answer. If the funny character is something else, such as a ' '
or control character or character with the 8th bit set, keep reading.

The classic answers are

rm -i some*pattern*that*matches*only*the*file*you*want

which asks you whether you want to remove each file matching
the indicated pattern; depending on your shell, this may not
work if the filename has a character with the 8th bit set (the
shell may strip that off);

and

rm -ri .

which asks you whether to remove each file in the directory.
Answer "y" to the problem file and "n" to everything else.
Unfortunately this doesn't work with many versions of rm. Also
unfortunately, this will walk through every subdirectory of ".",
so you might want to "chmod a-x" those directories temporarily
to make them unsearchable.

Always take a deep breath and think about what you're doing and
double check what you typed when you use rm's "-r" flag or a
wildcard on the command line;

and

find . -type f ... -ok rm '{}' \;

where "..." is a group of predicates that uniquely identify the
file. One possibility is to figure out the inode number of the
problem file (use "ls -i .") and then use

find . -inum 12345 -ok rm '{}' \;

or
find . -inum 12345 -ok mv '{}' new-file-name \;

"-ok" is a safety check - it will prompt you for confirmation of
the command it's about to execute. You can use "-exec" instead
to avoid the prompting, if you want to live dangerously, or if
you suspect that the filename may contain a funny character
sequence that will mess up your screen when printed.

What if the filename has a '/' in it?

These files really are special cases, and can only be created by
buggy kernel code (typically by implementations of NFS that don't
filter out illegal characters in file names from remote
machines.) The first thing to do is to try to understand exactly
why this problem is so strange.

Recall that Unix directories are simply pairs of filenames and
inode numbers. A directory essentially contains information
like this:

filename inode

file1 12345
file2.c 12349
file3 12347

Theoretically, '/' and '\0' are the only two characters that
cannot appear in a filename - '/' because it's used to separate
directories and files, and '\0' because it terminates a filename.

Unfortunately some implementations of NFS will blithely create
filenames with embedded slashes in response to requests from
remote machines. For instance, this could happen when someone on
a Mac or other non-Unix machine decides to create a remote NFS
file on your Unix machine with the date in the filename. Your
Unix directory then has this in it:

filename inode

91/02/07 12357

No amount of messing around with 'find' or 'rm' as described
above will delete this file, since those utilities and all other
Unix programs, are forced to interpret the '/' in the normal way.

Any ordinary program will eventually try to do
unlink("91/02/07"), which as far as the kernel is concerned means
"unlink the file 07 in the subdirectory 02 of directory 91", but
that's not what we have - we have a *FILE* named "91/02/07" in
the current directory. This is a subtle but crucial distinction.

What can you do in this case? The first thing to try is to
return to the Mac that created this crummy entry, and see if you
can convince it and your local NFS daemon to rename the file to
something without slashes.

If that doesn't work or isn't possible, you'll need help from
your system manager, who will have to try the one of the
following. Use "ls -i" to find the inode number of this bogus
file, then unmount the file system and use "clri" to clear the
inode, and "fsck" the file system with your fingers crossed.
This destroys the information in the file. If you want to keep
it, you can try:

create a new directory in the same parent directory as the one
containing the bad file name;

move everything you can (i.e. everything but the file with the
bad name) from the old directory to the new one;

do "ls -id" on the directory containing the file with the bad
name to get its inumber;

umount the file system;

"clri" the directory containing the file with the bad name;

"fsck" the file system.

Then, to find the file,

remount the file system;

rename the directory you created to have the name of the old
directory (since the old directory should have been blown away
by "fsck")

move the file out of "lost+found" into the directory with a
better name.

Alternatively, you can patch the directory the hard way by
crawling around in the raw file system. Use "fsdb", if you
have it.



Home FAQ