cp some/path/**/*.h 不包括所有深度的 .h 文件

cp some/path/**/*.h 不包括所有深度的 .h 文件

我正在尝试使用复制命令将目录和所有子目录中的所有 .h 文件复制到另一个文件夹中:

cp --parents -r tensorflow/lite/**/*.h libtensorflowlite-2.13.0-linux/include

上面的 glob 仅复制 .h 文件,tensorflow/lite/XXX/*.h并且不包含更下方(例如tensorflow/lite/XXX/XXX.h)或根目录(tensorflow/lite/*.h)中的 .h 文件。为了解决这个问题,我必须cp为所有预期的递归级别发出几个命令:

cp --parents -r tensorflow/lite/*.h libtensorflowlite-2.13.0-linux/include
cp --parents -r tensorflow/lite/**/*.h libtensorflowlite-2.13.0-linux/include
cp --parents -r tensorflow/lite/**/**/*.h libtensorflowlite-2.13.0-linux/include
cp --parents -r tensorflow/lite/**/**/**/*.h libtensorflowlite-2.13.0-linux/include

我知道我在这里遗漏了一些明显的东西。有没有更简单的方法来创建一个表示“所有子目录中以 .h 递归结尾的所有文件”的 glob?

答案1

**/匹配任何级别的子目录来自 1992 年的 zsh shell。

ksh93 确实在 2003 年复制了它,但为了向后兼容而默认禁用它(之前**与 相同*),通过set -G/启用set -o globstarbash是 2009 年最后添加该功能的 shell 之一,但它是按照 ksh93 的方式实现的(尽管在 5.0 之前是假的),并通过shopt -s globstar.

所以:

cp --parents tensorflow/lite/**/*.h libtensorflowlite-2.13.0-linux/include

可以在 zsh 中工作(或者在某种程度上fish默认**启用,尽管与 zsh 的工作方式略有不同),但您需要globstar首先在其他 shell 中启用该选项或等效选项:

set   -o globstar      # ksh93
set   -o extended-glob # yash
set      globstar      # tcsh
shopt -s globstar      # bash

有关更多详细信息,请参阅:ls * 、 ls ** 和 ls *** 的结果

答案2

此命令将查找及其子目录.h中的所有文件tensorflow/lite,并将它们及其相对路径复制到目标目录libtensorflowlite-2.13.0-linux/include

find tensorflow/lite -type f -name "*.h" -exec cp --parents {} libtensorflowlite-2.13.0-linux/include/ \;

find tensorflow/lite

  • 从目录开始搜索tensorflow/lite

-type f

  • 告诉 find 仅查找文件,而不查找目录。

-name "*.h"

  • 指定仅应考虑扩展名为 .h 的文件。

-exec cp --parents {} libtensorflowlite-2.13.0-linux/include \;

  • -execcp对每个找到的文件运行。

{}将替换为每个找到的文件的路径.h,并 --parents确保在目标目录中创建该文件的父目录libtensorflowlite-2.13.0-linux/include(如果它们不存在)。

相关内容