4

I'm trying to copy all .h files in a directory and all subdirectories into another folder using the copy command:

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

The above glob only copies .h files in tensorflow/lite/XXX/*.h and doesn't include .h files further down (eg. tensorflow/lite/XXX/XXX.h) or in the root (tensorflow/lite/*.h). To workaround this, I have to issue several cp commands for all expected levels of recursion:

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

I know I'm missing something obvious here. Is there an easier way to create a glob that says "all files ending in .h in all subdirectories recursively"?

1
  • 2
    Do you have the globstar option set in your shell? Commented Jul 20, 2023 at 17:01

2 Answers 2

20

**/ to match any level of subdirectories is from the zsh shell from 1992.

ksh93 did copy it in 2003, but made it disabled by default for backward compatibility (where before ** was the same as *), enabled with set -G/set -o globstar. bash was one of the last shells to add that feature in 2009 but did it à la ksh93 (though bogus until 5.0), enabled with shopt -s globstar.

So:

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

Would work in zsh (or to some extent fish where ** is enabled by default though works slightly differently from zsh), but you'd need to enable the globstar or equivalent option in other shells first:

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

For more details, see: The result of ls * , ls ** and ls ***

2
  • 3
    Ah this explained why the same command worked on my Mac but not on linux. Thanks Commented Jul 20, 2023 at 18:20
  • @Brad: This also explained why no other shell should be used. :D Commented Jul 21, 2023 at 17:24
6

This command will find all .h files in tensorflow/lite and its subdirectories and copy them with their relative paths to the destination directory 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

  • Starts the search from the tensorflow/lite directory.

-type f

  • Tells find to only look for files, not directories.

-name "*.h"

  • Specifies that only files with the .h extension should be considered.

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

  • -exec runs cp on each found file.

{} will be replaced with the path of each found .h file, and --parents ensures that the file's parent directories are created in the destination directory libtensorflowlite-2.13.0-linux/include if they don't exist.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.