【问题标题】:rm -rf /base-dir-path/*/work isn't the same as /base-dir-path/*/*/workrm -rf /base-dir-path/*/work 与 /base-dir-path/*/*/work 不同
【发布时间】:2015-07-30 17:36:42
【问题描述】:

如果我想从 linux/unix 的给定根目录中删除所有具有给定名称的子目录,你会认为你可以发出如下命令:

rm -rf /base-dir-path/*/work 

但是,在搜索任何名为“work”的子目录时,上述命令只会深入 1 个目录。为了实现我想要的,我最终用一个额外的 '*/' 重复相同的命令,直到 rm 返回 'rm: No match.',EG:

rm -rf /base-dir-path/*/*/*/work

有没有办法让rm 之类的命令在其通配符搜索中匹配/,这样我只需发出一个通配符* 字符?

【问题讨论】:

  • 我一般用tcsh,打印出来的版本如下:tcsh 6.12.00 (Astron) 2002-07-23 (sparc-sun-solaris)
  • 无论如何,关于非 POSIX shell 的问题需要明确命名该 shell。当你问一个标签为“shell”的问题时,人们会认为它是一个 POSIX sh 兼容/衍生的。
  • 顺便说一下——在 UNIX 上(与 Windows 不同),根本不是命令(如 rm)进行任何匹配; shell 自己执行 glob 扩展,并将结果名称列表传递给底层命令;该命令不参与其中,实际上无法知道用户输入的是 glob 表达式而不是明确的名称列表。
  • 这实际上是一个非常有用的信息:)
  • 修复了标签...撒谎是一种严厉的方式来描述某人何时歪曲他们的问题(撒谎意味着意图,错误是无意的)。说清楚……我确实在 RHEL 上使用 Bash,在 SunOS 上使用 tcsh……我只提到了上面的 tcsh,因为一般来说,当命令在那里工作时,它们在其他任何地方都可以工作。

标签: shell unix wildcard solaris tcsh


【解决方案1】:

在 tcsh 6.18.00 或更高版本上:

set globstar
rm -rf /base-path/path/**/work

在 bash 4.0 或更高版本上:

shopt -s globstar
rm -rf /base-dir/path/**/work

在 ksh 上:

set -o globstar # or set -G
rm -rf /base-dir/path/**/work

在 zsh 上:

rm -rf /base-dir/path/**/work

或者,find 符合 POSIX 2006 修订版:

find /base-dir/path -type d -name work -exec rm -rf -- '{}' +

如果您没有find-exec ... {} +,那么您可能也没有xargs -0,并且需要以低效的方式来确保安全:

find /base-dir/path -type d -name work -exec rm -rf -- '{}' ';'

【讨论】:

  • 我使用的 RHEL 上的 bash 版本是 3.2.25 :| ... 更冗长的 find 命令是我试图避免的,但我想我只需要更适应它,除非其他人有其他建议
  • 如果有人读到这篇文章,我的问题的真正答案是查尔斯·达菲对原帖的评论,他解释了如何相对于 shell 命令执行全局扩展......
  • @user3462694 请注意,使用** 也适用于tcsh。您将需要使用set globstar(默认关闭)。您还可以使用 *** 来下降到符号链接。从 2012 年 1 月起,您将需要 tcsh 6.18.00。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-30
  • 2015-06-26
  • 2011-02-28
  • 2021-12-04
相关资源
最近更新 更多