2

I want to copy all binaries from /sourcedir and its sub-dirs to /destdir. Basically, all files with: no extension, and all files with *.a, *.so, *.ko, and exclude from copy: Makefile and *.depend. Exclude file copy from the sub-dir named "excludeDir". The command should place all binaries in a single folder.

I have tried the following from bash:

find /my/sourcedir/ -mindepth 2 -type f -not -iname "excludeDir" -or "*.c" -or "*.h" -or "makefile" -print -exec cp {} /my/destdir \;

bash script yields the following error:

find: paths must precede expression: `*.c'

The part that is giving me trouble are the exclusions (files: *.h, *.c, Makefile, and the sub-directory: "excludeDir" )

Using mjb2kmn's advice the following command does well except for globbing.

find /opt/ppmac-exp/ -mindepth 2 -not -iname *.c -not -iname *.cpp -not -iname *.cc -not -iname *.cs -not -iname *.h -not -iname *.cfg -not -iname *.sh -not -iname *.layout -not -iname *.depend -not -iname Makefile -not -iname Makefile* -type f -print -exec cp {} /opt/build \;
3
  • If you mean -iname to apply to ".c"? If so, you need to use a complete expression. ... -iname "excludeDir" -or -iname ".c" -or ... Also the -print and -exec options might need to be before the -not since they always return true and might negate the match.
    – virullius
    Commented Dec 4, 2019 at 19:30
  • Correct mjb2kmn I want to exclude all *.c and *.h files from the copy process. Additionally it would be nice but not essential to exclude the excludeDir from the sub-directories that files are copied from.
    – masher
    Commented Dec 4, 2019 at 20:05
  • Thank you that helped take care of the bash error, but now there is a globbing problem.
    – masher
    Commented Dec 4, 2019 at 20:50

3 Answers 3

1

... with the help of mjb2kmn and dash-o on stackoverflow, this worked and prevented globbing. Thank you all!

find /my/sourcedir/ -mindepth 2 -type f \
 \( -not -iname "excludeDir" \
    -not -iname '*.c' \
    -not -iname '*.h' \
    -not -iname '.ssh' \
    -not -iname "Makefile" \) \
 -exec cp {} /my/destdir \;

0

I realize the original poster asked about doing this in find.

What you are doing is fairly complicated to express easily in find.

If you have perl on the system, you might do better using find2perl. It takes your syntax, and writes a little perl script for you that you can just run; or edit to add more checks and such like. See https://perldoc.perl.org/5.8.8/find2perl.html

Or, simply define the names of what you want to copy in the Makefile, and make a target that does the copy directly as a part of the makefile...

0

There's a version of this if you want to preserve the directory structure of the copied elements, as well. Two preconditions make it much easier:

  1. You run it from the source directory (to arrange for relative paths in the find output) — it's possible to work around this restriction, but requires a lot more processing of the find output.
  2. You use a helper script to process each file path that comes out of find, since running subshell commands in the find -exec doesn't work.

Setup

cat > /tmp/helper.sh <<__EOF__
#!/bin/sh
mkdir -p "/my/destdir/$(dirname "$1")"
cp -v "$1" "/my/destdir/$(dirname "$1")/"
__EOF__
chmod +x /tmp/helper.sh

Execution

cd /my/sourcedir
find -mindepth 2 -type f \
  [conditions] \
-exec /tmp/helper.sh "{}" \;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .