如何进入当前路径下的每个目录并执行脚本

如何进入当前路径下的每个目录并执行脚本

我想要进入ls命令返回的每个目录并执行脚本。

我尝试了这个(以及许多其他方法),但就是不起作用

ls  | awk '{print $1" && pwd"}' | xargs cd

没有 for 循环该怎么做?

答案1

find . -type d -exec bash -c 'cd "$0" && pwd' {} \;

交换pwd您的脚本。.如果不是“当前”目录,则交换根目录名称。

您必须bash -c "..."根据工作方式包装 exec 子句-execcd在其有限的环境中不存在,但正如您通过运行上述命令所看到的,当您引入 bash 来执行该作业时,一切都按预期运行。

编辑:我不知道为什么 2011 Oli 没有想到-execdir但这可能是一个更快的解决方案:

find . -type d -execdir pwd \;

答案2

如果可以的话,请find按照其他答案中的建议使用,xargs这几乎总是应该避免的。

但如果您仍然想使用xargs,一种可能的替代方法如下:

printf '%s\0' */ | xargs -0 -L1 bash -c 'cd -- "$1" && pwd' _

一些说明:

  1. */由于结尾有斜杠,因此扩展到当前文件夹中的目录列表

  2. printf\0(空字节)将元素分隔为每行一个

  3. 该选项-L1使其xargs对每个输入行执行一次,并且该选项-0使其在空字节上分离输入:文件名可以包含任何字符,命令不会中断!

  4. bash删除双引号并将其作为单个参数传递给内联脚本,但cd应再次加上双引号以将其解释为单个字符串;使用--使该cd命令能够有效对抗以连字符开头的文件名

  5. 以避免奇怪的$0作为参数使用,通常会放置第一个伪参数_

答案3

不应该解析ls首先。

您可以使用 GNUfind来实现它及其-execdir参数,例如:

find . -type d -execdir realpath "{}" ';'

或者更实际的例子:

find . -name .git -type d -execdir git pull -v ';'

以下是版本xargs

find . -type d -print0 | xargs -0 -I% sh -c 'cd "%" && pwd && echo Do stuff'

有关更多示例,请参阅:如何进入各个目录并执行命令?在 SO

答案4

出于好奇,我尝试采用你的例子并使其发挥作用。没有理由使用这种技术而不是find命令。

笔记:谢谢恩佐替布需要指出的是,这对于包含空格或任何其他字符的目录名称不起作用,因为这些字符会使awk目录名称被认为由多个字段组成。

为了使您的示例正常工作,应该进行一些调整。但首先看一下代码:

ls -l | grep ^d | awk '{print $NF}' | xargs -n 1 bash -c 'cd $0; ls'

前两个命令确保只列出目录。由于ls长列表包含 ad作为目录的第一个字符,因此该grep命令仅选择这些行。

每行只显示awk最后一列。是用于保存最大字段数的NF内置变量。因此打印时将显示最后一列。awk$NF

最后xargs需要驯服,以便每次只使用一个参数来运行指定的脚本。(我知道这有点违背了它的目的。)否则,脚本无法在每个目录中运行没有 for 循环

为了绕过内置cd屏障,我们用 进行调用bash-c另请注意,$0成为第一个参数,而不是$1

相关内容