答案摘要:虽然文献宣传“-execdir”比“-exec”更安全,但不要忽略操作差异。前者不是后者的简单重新实现。此外,当专门使用 find 进行交互式删除时,通过“-okdir”选项执行“rm -f”也是可行的。同样对于稍微复杂的结构。
我正在尝试学习“查找”命令,但无法理解其输出。如果这是重复的,我深表歉意,但问题陈述有点复杂,对谷歌来说很难。
让我设置一个宠物箱:我从某个目录(“.”)开始,有两个子目录“A”和“B”。在这两个文件中,都有一个名为“hello.c”的文件。
所以,例如,
find . -name "hello.c"
Run Code Online (Sandbox Code Playgroud)
会像这样打印:
./A/hello.c
./B/hello.c
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。我迷路的是当我尝试使用“-execdir”选项做一些事情时;假设我想使用交互式删除。然后:
find . -name "hello.c" -execdir rm -i {} \;
Run Code Online (Sandbox Code Playgroud)
或类似。我期望的是
rm: remove regular file "./A/hello.c"?
Run Code Online (Sandbox Code Playgroud)
然后,回答那个,目录“B”中的“hello.c”的类似提示。不幸的是,实际出现的是
rm: remove regular file "./hello.c"?
Run Code Online (Sandbox Code Playgroud)
在这个小例子中,我可以合理地推断它是在询问“./A/hello.c”,但是如果将这个例子放大,那么你会得到几十个文件,它们的路径名都被截断为“./”。而且我无法区分数十个“./hello.c”,这与它们各自所在的子目录无关。
所以,我的问题归结为希望通过“-execdir”打印更完整的路径名。我能听到关于联机帮助页中哪些微妙之处的提示吗?关于“{}”替换的说法很少。或者,如果有更好的方法来管理这种特殊情况(交互式删除),我也想听听,因为我不确定我的方法是否是最佳实践。
GNU 的手册页部分地这样find
描述-execdir
:
类似
-exec
,但指定的命令是从包含匹配文件的子目录运行的,该子目录通常不是您启动的目录find
。
所以没有真正的微妙之处。-exec
从您运行的目录调用命令find
(因此需要提供相对于该目录的路径或从根目录的绝对路径),并-execdir
从包含文件的目录调用命令,因此不需要提供完整的路径,所以没有。
要获得您所追求的行为,您应该使用-exec
而不是-execdir
.
您可以通过将您的rm
调用替换为例如echo
简单地打印参数列表(在本例中为文件名)来演示此行为。或者使用-print
which 无需调用外部命令即可完成此操作。(注意:-print
如果没有给出,也是默认操作。)
如果您不需要确认,则可以使用-delete
。对于大量文件,这也可能更有效,因为它避免了rm
一次又一次地调用。