I made a typo:
$ history
169 9:34 la /usr/local/etc/
170 9:35 sudo mkdir ^C
171 9:36 sudo mkdir /usr/local/etc/dnsmasq.d
Now I have a file that is called ^C (ctrl+C)!!
When I use ls
I just see a questionmark (probably due to the locale?)
% ls -al
total 60
drwxr-xr-x 2 root wheel 512 Jan 21 09:35 ? <- this one
drwxr-xr-x 5 admin wheel 512 Jan 21 16:24 .
drwxr-xr-x 3 root wheel 512 Jan 20 14:29 ..
-rw-r--r-- 1 admin nobody 1114 Jan 20 19:10 .cshrc
-rw------- 1 admin wheel 6002 Jan 21 15:27 .history
-rw-r--r-- 1 admin nobody 182 Jan 20 14:29 .login
-rw-r--r-- 1 admin nobody 91 Jan 20 14:29 .login_conf
-rw------- 1 admin nobody 301 Jan 20 14:29 .mail_aliases
-rw-r--r-- 1 admin nobody 271 Jan 20 19:04 .mailrc
-rw-r--r-- 1 admin nobody 726 Jan 20 19:05 .profile
-rw------- 1 admin nobody 212 Jan 20 14:29 .rhosts
-rw-r--r-- 1 admin nobody 911 Jan 20 19:06 .shrc
drwx------ 2 admin nobody 512 Jan 20 15:05 .ssh
drwxr-xr-x 2 admin wheel 512 Jan 20 19:08 bin
and
% ls -i
3611537 ? 3611534 bin
I want to remove this file. I try mv
and when using tab-completion it shows me:
% mv
^C/ bin/
Obviously I can't type a ^C :-/ How do I remove this file?
^V
(ctrl+v) works as a kind of escape sequence for the next key-press, inserting the associated value instead of taking whatever action that would normally be associated.Making use of this,
^V^C
(ctrl+v, ctrl+c) ought to work for entering your difficult filename in the terminal.You may also remove the file by inode:
Whatever you do, for God's sake, do not put
-delete
before-inum
:Congratulations, you just wiped out all your files. With
find
, argument order matters!Another option is to use
rm -ri ./*
;rm
will ask you before deleting any file and directory, so you just need to replyy
to the "bad" file, andn
to all the others.Actually, in your case you can even cut down the number of replies needed by doing
rm -ri ./?
, as your "bad" file is just one character long.One option is to look up the file name with something other than
ls
. If you know it was produced by a verbatim Ctrl+C, you can find the ASCII character produced using a table of control characters, or with a more friendly interface like the one provided by Python:Another option would be to look at a hex dump of the output of
ls
, using e.g.hexdump
.Then you can delete the file with (for example) this bash command:
(The double quotes are only needed if the character you're trying to print is in your
IFS
variable, such as\x20
or\x0A
, but it's a good habit to quote command substitutions unless you know you want the shell to perform field splitting, etc.)Often in this kind of situations it is easy to come up with a wildcard pattern that matches the relevant file.
In your case, this would be simply
?
(matching all file names with precisely one character).Just check that it really matches what you want:
And then remove the directory:
You can also combine this with tab completion. You can type
and press tab, and e.g. in bash it will be replaced by
and you can then hit enter and it does what you want.
You can use Midnight Commander (mc) to delete the file - just select with up/down buttons and press F8.
I did that occasionally when file names had strange characters due to encoding.
Yet another way: use
stat
to get an escaped representation of the directory name:Now you know a representation of the file name, so you can remove the file by name using
printf
:Or, if you're using bash, you can avoid
printf
:A solution that has worked for me is:
to cycle through the available files until I find the one I want to remove.
But you do need to have the necessary settings in your shell for that to work.
The easiest way is to move everything to the temporary directory and then
rm -r DIRNAME
.If it's the only empty directory (or you don't care about removing other empty directories), use
rmdir */
. You will get error messages fromrmdir
about not being able to remove non-empty directories, but that's fine. GNUrmdir
supports--ignore-fail-on-non-empty
, or you could2>/dev/null
.The trailing
/
makes the glob only match directory names.You can check ahead of time what empty directories exist under the current one using
find -maxdepth 1 -type d -empty -ls
. (And you can change the-ls
to-delete
if you want).You could use a more-specific glob expression like
rmdir [^A-Za-z0-9._]/
to match directories that start with a non-alphanumeric or underscore filename. I also included.
, but glob expressions don't match.
normally anyway.As others have pointed out, you can limit it to single-character names with a glob of
?
:rmdir ?/
rmdir
doesn't have a-i
option the wayrm
does, presumably because empty directories are usually not valuable and can just be recreated.