I'm trying to run a command similar to the one below in a bash script. It should search through all subfolders of $sourcedir
and copy all files of a certain type to the root level of $targetdir
.
#!/bin/bash
# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;
This seems to be pretty close, except that {}
isn't being passed in as $2
to -exec sh -c ...
I would like to do this as close to the "right way" as possible, with tolerance for special characters in filenames (specifically single quote characters).
Edit: I see people suggesting using xargs
or argument chaining. I was under the impression that this is only ok for a limited number of arguments. If I have, for example, thousands of .jpg files I'm trying to copy from a number of gallery directories into a giant slideshow directory, will the solutions chaining arguments still work?
Edit 2: My problem was I was missing a _
before my first option to sh in the -exec
command. For anyone who is curious about how to make the find command work, add the _
and everything will be fine:
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" "$targetdir" \;
I have accepted an answer below though because it accomplishes the same task, but is more efficient and elegant.
Best Answer
You want to copy files of a specific type, to a specific directory? This is best done with
xargs
, and you don't even need thatsh
. This is a more appropriate way to do it, should also run more efficiently.If you need to handle special file names, then use
NULL
as your seperator