【问题标题】:Using both command substitution and executing a shell within GNU "find" exec command在 GNU “find” exec 命令中同时使用命令替换和执行 shell
【发布时间】:2021-07-16 04:22:06
【问题描述】:

我是 bash 新手,我正在尝试做一些看起来相当简单但遇到问题的事情。

我正在尝试搜索具有非常通用但非唯一名称的文件(例如 analysis.uniqueExt,但也可能是 sorted_result.uniqueExt),该文件可以位于从不同“查找”中找到的目录的一个特定子目录中询问。然后我想将该文件复制到我的个人目录中,同时将文件重命名为更具描述性的内容,提示其原始位置。

这是我尝试过的一个示例:

case=/home/data/ABC_123 # In reality this is coming from a different query successfully
specific_id=ABC_123 # This was extracted from the previous variable
OUTDIR=/my/personal/directory

mkdir -p $OUT_DIR/$this_folder

find $case/subfolder/ -type f -name "*.uniqueExt" -exec sh -c 'cp "$1" ${OUT_DIR}/${specific_id}/$(basename "$1")' sh {} \;

这不起作用,因为 OUT_DIR 和 specific_id 不在 -exec 命令创建的内壳范围内。

所以我尝试了另一种方式:

find $case/subfolder/ -type f -name "*.uniqueExt" -exec cp {} ${OUT_DIR}/${specific_id}/$(basename {}) \;

但是现在我无法提取在“查找”查询中找到的文件的基本名称,因为我没有调用 shell 来执行此操作。

有没有一种方法可以在示例 #1 中正确确定变量的范围,或者在示例 #2 中执行 basename 函数来完成此操作?或者可能有一个完全不同的解决方案(可能涉及多个 -exec 调用?或者可能只是将查找结果通过管道传输到 xargs?)。

感谢您的帮助!

【问题讨论】:

    标签: bash find


    【解决方案1】:

    您需要导出变量,因为您在与分配它们的shell进程不同的shell进程中使用它们。

    导出变量使它们在后代进程中可用。

    export specific_id=ABC_123 # This was extracted from the previous variable
    export OUTDIR=/my/personal/directory
    

    但是,您实际上并不需要为此使用 shell。你可以使用

    find $case/subfolder/ -type f -name "*.uniqueExt" -exec cp -t "$OUTDIR/$specific_id/" {} +
    

    您不必自己调用basename,因为将文件复制到目标目录会自动使用基本名称作为目标文件名。

    在我的版本中,我使用-t 选项,因此我可以将目标目录放在首位。这允许它使用+ 变体将所有找到的文件名放在一个命令中,而不是为每个文件单独运行cp

    【讨论】:

    • 更准确地说:exporting 他们使他们(嗯,他们的副本)可用于导出它们的进程的子进程。由于find 是运行脚本的shell 的子进程,而findsh -c ... 作为其自身的子进程运行,因此该子进程shell 将继承这些值。 (我添加这个是因为很多人希望导出的变量传递给 parent 进程,而这不会发生。)
    • 我添加了一些说明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多