【问题标题】:find folders and cd into them找到文件夹并 cd 进入它们
【发布时间】:2014-12-11 12:15:22
【问题描述】:

我想写一个结构如下的短脚本:

 find the right folders
 cd into them
 replace an item

所以我的问题是我从find 获得了正确的文件夹,但我不知道如何为find 给我的每一行执行操作。我尝试了这样的 for 循环:

for item in $(find command)
  do magic for item
done

但问题是这个命令会打印相对路径名,如果我的路径中有空格,它会在此时分割路径。

希望你能理解我的问题并给我一个提示。

【问题讨论】:

  • find . -name blah -exec do_stuff_to {} \;
  • 查看find -execxargs

标签: bash shell find


【解决方案1】:

您可以直接使用 find 的 -exec 选项运行命令:

find . -name some_name -exec your_command {} \;

【讨论】:

  • pwd 在那里是因为问题想使用绝对路径。如果你使用 .它将返回相对路径。所以我认为pwd 实际上很有用。你说什么?
  • 如果 PATH 包含路径,则您的 pwd 不起作用。如果你“真的”需要使用它,你应该用“pwd”引用
【解决方案2】:

一种方法是:

find command -print0 |
while IFS= read -r -d '' item ; do
    ... "$item" ...
done

-print0read ... -d '' 导致使用 NUL 字符分隔路径,并确保代码适用于所有路径,包括包含空格和换行符的路径。将IFS 设置为空并将-r 选项设置为read 可防止read 修改路径。

请注意,while 循环在子 shell 中运行,因此在循环完成后,其中设置的变量将不可见。如果这是一个问题,解决它的一种方法是使用进程替换而不是管道:

while IFS= ...
    ...
done < <(find command -print0)

如果您有 Bash 4.2 或更高版本,另一个选项是使用 lastpipe 选项 (shopt -s lastpipe) 使管道中的最后一个命令在当前 shell 中运行。

【讨论】:

  • 这个解决方案在我的情况下运行良好。谢谢大家
【解决方案3】:

如果你想找到的模式足够简单并且你有 bash 4,你可能不需要find。在这种情况下,您可以使用 globstar 代替递归通配符:

#!/bin/bash

shopt -s globstar
for directory in **/*pattern*/; do
    (
    cd "$directory"
    do stuff
    )
done

括号使每个操作都在子shell中发生。这可能会产生性能成本,但通常不会,这意味着您不必每次都记住cd

如果globstar 不是一个选项(因为您的find 指令不是一个简单的模式,或者因为您没有支持它的shell),您可以以类似的方式使用find

find . -whatever -exec bash -c 'cd "$1" && do stuff' _ {} \;

您可以使用+ 而不是; 来每次将多个参数传递给bash,但是每个shell 执行一个目录(; 会这样做)与使用上面的子shell 表达式具有相似的好处和成本.

【讨论】:

    猜你喜欢
    • 2023-01-11
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    • 2022-08-18
    • 2021-10-15
    相关资源
    最近更新 更多