如何删除名称为“--”的目录(单引号是名称的一部分)

Kar*_*nen 20 linux command-line

一个写得不好的脚本'--'在我的主目录中创建了一个名为(包括单引号)的目录。

当我cd进入该目录时,我将返回到我的主目录。

我想删除该项目,但不知道该怎么做。转义目录名称中的部分或全部字符,返回No such file or directory

Linux版本

Linux version 5.11.0-1022-aws (buildd@lgw01-amd64-036) (gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #23~20.04.1-Ubuntu SMP Mon Nov 15 14:03:19 UTC 2021
Run Code Online (Sandbox Code Playgroud)

ter*_*don 44

就您而言,由于您实际上将引号作为名称的一部分,因此您可以执行以下操作:

rm -r \'--\'
Run Code Online (Sandbox Code Playgroud)

或者

rmdir \'--\'
Run Code Online (Sandbox Code Playgroud)

更常见的情况是引号不是名称的一部分,因此您还需要处理名称看起来像一个选项(以 开头-)这一事实。在这种情况下,经典的方法是:

  1. 用于--表示选项的结束,以便 后面的任何内容都--不会被解析为选项,即使它以 开头-

     rmdir -- "'--'"
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用完整路径或仅使用完整路径./(但您还需要引用名称以保护'免受 shell 的影响):

     rmdir ./"'--'"
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用 GNU find

     find . -name "'--'" -delete
    
    Run Code Online (Sandbox Code Playgroud)
  4. 使用其他东西。像 Perl 一样:

     perl -e "rmdir(\"'--'\")"
    
    Run Code Online (Sandbox Code Playgroud)

请注意,以上所有内容均假设该目录为空。如果不是,只需使用其中之一即可:

rm -r ./"'--'"
Run Code Online (Sandbox Code Playgroud)

或者

rm -r -- "'--'"
Run Code Online (Sandbox Code Playgroud)

  • @PeterCordes 确实是的。这个答案的部分内容是在明确名称中包含引号之前写的。 (3认同)
  • 如果 `rmdir \'--\'` 有效,则 `rmdir "'--'"` 也将工作,而不需要 `--` 分隔符,因为两者都将相同的参数列表传递给 `rmdir`。该选项不以“-”开头。 (2认同)

use*_*001 28

对于带有引号、反斜杠、空格、换行符等的“有趣”名称,如其他答案所示,需要引用和/或转义。

但是,如果您尝试从终端以交互方式使用文件名(而不是脚本),制表符补全对于您进行引用确实很有帮助。

使用您拥有的目录名称,只需键入:

rm -r \'<tab>
Run Code Online (Sandbox Code Playgroud)

Tab 键在哪里,位于键盘上<tab>字母的左侧。Q我们使用\'转义第一个单引号字符,因为它是一个特殊字符。

如果没有任何其他以单引号字符开头的文件/目录,bash 将完成文件名,并正确转义:

rm -r \'--\'/
Run Code Online (Sandbox Code Playgroud)

注意:似乎不需要--按照其他答案的建议添加“选项结束”序列,因为文件名的第一个字母不是-减号字符。

  • 太棒了,@KarlHakkarainen。请选择复选标记图标来接受答案。这有助于网站的正常运行。:) 请参阅 https://stackoverflow.com/help/someone-answers 欢迎使用 Unix 和 Linux StackExchange。 (2认同)
  • 除了制表符补全之外,全局扩展对于您不确定如何轻松键入或引用第一个字符的文件来说是另一个方便的技巧。`rm -i *--*` 应该可以很好地工作,而 `-i` 可以让您以交互方式跳过任何您不想删除的匹配项。 (2认同)

Fed*_*rev 12

$ mkdir -- \'--\'
$ ls
'--'
$ rmdir -- \'--\'
$ ls
$
Run Code Online (Sandbox Code Playgroud)


dot*_*hen 7

我处理无法键入或制表符完成的文件名(例如非打印字符)的首选方法是通过 inode 删除它们。该ls标志-i将每个文件的索引节点号添加到输出中。

$ ls
bar.c  foo.c

$ ls -i
5646079 bar.c  5642988 foo.c

$ find . -maxdepth 1 -inum 5642988 -delete

$ ls
bar.c
Run Code Online (Sandbox Code Playgroud)

下面是一个文件名仅包含不可打印字符的示例:

$ ls -il
total 0
5646079 -rw-rw-r-- 1 oem oem 0 Dec 16 09:49 bar.c
5642988 -rw-rw-r-- 1 oem oem 0 Dec 16 10:02 foo.c
5646169 -rw-rw-r-- 1 oem oem 0 Dec 16 10:05

$ find . -maxdepth 1 -inum 5646169 -delete

$ ls -il
total 0
5646079 -rw-rw-r-- 1 oem oem 0 Dec 16 09:49 bar.c
5642988 -rw-rw-r-- 1 oem oem 0 Dec 16 10:02 foo.c
Run Code Online (Sandbox Code Playgroud)

请注意,参数的顺序find很重要。

此外,如果同一目录中的文件有多个硬链接,这会将它们全部删除。

  • 我没有尝试使用这种技术,但根据您的解释,我预测它将删除尽可能多的同一文件的名称,而不仅仅是有问题的/不需要的名称。 (3认同)
  • @dotancohen:嗯,我们正在讨论硬链接,因此根据同一文件系统中的定义。我同意“-maxdepth 1”将防止删除指定目录之外的其他名称(目录条目),但目录内也可以有多个硬链接。 (2认同)