1. Overview

Sometimes, we can encounter situations where we want to delete files that have filenames with certain characters like symbols, whitespaces, tabs, and other non-printable characters. In these cases, we can’t usually perform actions like deletion with a regular rm command, especially when using an ASCII-based terminal.

In this tutorial, we’ll look at common effective methods to delete any file with non-printable characters in its name.

2. Viewing Non-printable Filenames

Before even trying to start the deletion process, we should first list the content of our working directory in an acceptable manner to understand exactly what’s going on and how to handle deleting any target object.

First, let’s use the ls command to list the content of the current directory:

$ ls
'      '               ␴__␴                    '␴  μ ␴'$'\342\220\264''Ξ'
'~$iscord.docx'        ␴␴␴␴␴␴␴␴␴␴                               
''$'\302\226'         '␴ω␴␴␴␴'$'\342\220\264'   
                                               
''$'\302\226''Λ---ω'   ␣␣␣␣␣␣␣␣
'␴?␴??␴??::␴?␴'        ␴  μ  μ  Ω Ω

Notably, the output is unusual and looks wrong due to the rare characters in the filenames.

So, to see file-to-name mappings, we’ll use the -l option for the verbose long list format:

$ ls -l
total 13
-rw-r--r-- 1 ZZ 197121   4 Nov  6 07:08 '      '
-rw-r--r-- 1 ZZ 197121 162 Apr 16  2022 '~$iscord.docx'
-rw-r--r-- 1 ZZ 197121   6 Nov  6 06:03 ''$'\302\226'
-rw-r--r-- 1 ZZ 197121   4 Nov  6 06:01 ''$'\302\226''Λ---ω'
-rw-r--r-- 1 ZZ 197121   4 Nov  6 06:13 '␴?␴??␴??::␴?␴'
-rw-r--r-- 1 ZZ 197121   4 Nov  6 06:12  ␴__␴
-rw-r--r-- 1 ZZ 197121   4 Nov  6 06:14  ␴␴␴␴␴␴␴␴␴␴␴␴␴␴␴␴␴
-rw-r--r-- 1 ZZ 197121   4 Nov  6 06:18 '␴ω␴␴␣␦'$'\342\220\264'
-rw-r--r-- 1 ZZ 197121   4 Nov  6 06:16  ␣␣␣␣␣␣␣␣
-rw-r--r-- 1 ZZ 197121   4 Nov  6 06:26  ␣   μ   μ   Ω  Ω
-rw-r--r-- 1 ZZ 197121  14 Nov  6 06:23 '␣   μ  ␴'$'\342\220\264''Ξ'
-rw-r--r-- 1 ZZ 197121   4 Nov  6 06:27                
-rw-r--r-- 1 ZZ 197121   4 Nov  6 06:27                          

Now, the output is more human-friendly. However, we can still preemptively assume that there will be an issue if we were to use one of the files as an argument for rm. After all, we can see that there are even some blank names.

3. Using ANSI-C Quoting

As we already saw, the ls command provides some help by enclosing several of the filenames in an ANSI-C quoting style. This is a clear indication that the filename has non-printable characters.

In this situation, we can still use the standard rm command to delete some of the items. To do so, we just pass the exact name as listed by ls:

$ rm ''$'\302\226'

We can also use the $ special character before enclosing the filename in single quotes:

$ rm $'\356\200\215'

So, the rm command coupled with ANSI-C quoting gets the data deleted successfully.

Now, let’s pass an item’s name to rm without using the ANSI-C quoting:

$ rm '\026\033'
rm: cannot remove '\026\033': No such file or directory

We can see that the shell complained with a No such file or directory error.

Of course, passing filenames with an ANSI-C quoting format to the rm command is not always effective or efficient.

4. Using Inode Numbers

In the ls output from earlier, we can’t simply type or copy some filenames so we can delete them. Similarly, selecting the item by relying on tab completion won’t work either.

Meanwhile, another property that defines files uniquely other than their path is their inode number. In fact, we can list our items with their unique inode number via the -i option of ls:

$ ls -li
total 11
...
6517085 -rw-r--r-- 1 ZZ 197121   4 Nov  6 06:18 '␴ω␴␴␣␦'$'\342\220\264'
7826050 -rw-r--r-- 1 ZZ 197121   3 Nov  9 04:23 ''$'\356\200\215\356\200\215\356\200\215'
4685554 -rw-r--r-- 1 ZZ 197121   4 Nov  6 06:27                        

Now, the ls command prints the inodes in the first column of the output.

At this point, we can delete the desired file by passing its inode number to the –inum switch of the find command:

$ find . -inum 4685554 -exec rm -i {} \;
rm: remove regular file './                '? y

In the above code snippet, we’ve executed the find -inum command to search for the target file by its inode number. After that, the -exec argument passes the selected file path to rm for deletion. To avoid mistakes, we also use the -i flag of rm to request confirmation.

5. Using rm Interactive Option With Bash Globbing

Using globbing isn’t very efficient for our purposes, but it’s definitely effective when we need to delete files with names containing non-printable characters.

In this method, we pass an asterisk character (shell glob) to the rm command coupled with the -i switch. This makes the command go over all the content within our directory and selectively delete the ones we confirm:

$ rm -i *
rm: remove regular file '      '?y
rm: remove regular file '                            '?y
...

As we can see, the interactive option in rm with the *  wildcard argument will list each file and ask us if we want it removed.

6. Using the Vim Text Editor

Surprisingly, another great way to delete files with characters that can’t be displayed by the terminal is by using the Vim text editor.

To achieve that, we simply run vim in the desired directory:

$ vim .

Next, we can navigate through the list of files by using the Up and Down or the J and K keys:

vim files list

After choosing the target file, we simply use Shift+D, type y or yes, and hit the Return key to delete it.

7. Conclusion

In this article, we discussed how to delete files with non-printable characters that can’t be displayed by the terminal. Furthermore, we went over common methods to delete such files. Finally, we learned how to avoid shell errors and other unusual problems during the deletion process.