Search code examples
macosshellcommand-linecommand-line-interfacezsh

Why when deleting a file named ^V^V in Zsh it deletes all visible files with it?


I was trying to delete a file named ^V^V (created by fooling around in Vim), but failed because I didn't know how to escape the carets. So I copied and pasted it instead and used the trash command (cli utility for MacOS) and it deleted all visible files with it. I noticed because the Alacritty terminal was warning me the config file was gone.

This is the command I typed:

trash ^V^V

^V^V meaning caret and uppercase v, not Ctrl V.

Here you can get the Cli utility (recommended if you use MacOS): https://github.ink/sindresorhus/macos-trash

The result was it sent to the trash all files in the current directory.


Solution

  • According to the man page zshexpn, in the context of filename generation, ^ takes on a special meaning, if extended globbing is set:

    ^x

    (Requires EXTENDED_GLOB to be set.) Matches anything except the pattern x. This has a higher precedence than '/', so '^foo/bar' will search directories in '.' except './foo' for a file named 'bar'.

    Assuming you have extended glob set, ^V^V (that is the four byte sequence, not two times the escape-code) expands to everything not starting with an upper case 'V'. Example session:

    ╓╴                                                                                               z[10:21]╶╖
    ╙╴~/scratch/zsh❯ ls                                                                         07:31 17:40 ╜
     B_file.txt   F_file.txt   V_file.txt
    ╓╴                                                                                               z[10:21]╶╖
    ╙╴~/scratch/zsh❯ ls ^V^V                                                                    07:31 17:40╜
     B_file.txt   F_file.txt