I want to copy all the .html files from myDir and its subdirectories to ~/otherDir. Here’s what I tried, but it doesn’t work:
$ find myDir -name *.html -print | xargs -0 cp ~/otherDir
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
First of all, the shell is globbing the ‘*’ for you. Either escape it with or use quotes around *.html
Like so:
find myDir -name "*.html" or find myDir -name *.html
Skip the use of xargs with find‘s -exec switch:
find myDir -name "*.html" -exec cp {} ~/otherDir ;
This works because {} takes the place of the file that find found, and is executed once for each match.
Also note that this will flatten the copy of the source directory. Example:
myDir/a.html myDir/b/c.html
will yield
otherdir/a.html otherdir/c.html
Method 2
So you want to copy all the .html files in some source directory and its subdirectories, all to a single directory (i.e. collapsing the hierarchy)?
POSIX Standard:
find myDir -name '*.html' -type f -exec sh -c 'cp "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="684c28">[email protected]</a>" "$0"' ~/otherDir {} +
Note that ~/otherDir becomes parameter 0 to the intermediate shell, which allows for the source files to be precisely "[email protected]". Leaving the target directory outside the shell has the additional advantage that you won’t run into quoting issues if that’s a variable in the parent shell script (-exec sh -c 'cp "[email protected]" "$0"' "$target").
For older systems that don’t have find … -exec … +:
find myDir -name '*.html' -type f -exec cp {} ~/otherDir ;
I your shell is bash ≥4 or zsh:
shopt -s globstar # only for bash, put it in your `.bashrc` cp myDir/**/*.html ~/otherDir/
Method 3
find myDir -name '*.html' -print0 | xargs -0 -J % cp % ~/otherdir
Method 4
Try
find myDir -name '*.html' -exec cp -t ~/otherdir {} +
One problem with this approach is that it doesn’t create any subdirectories so all files get put in ~/otherDir and files that are named the same but in different parts of the myDir tree don’t get copied.
If this would cause you a problem then you can use the following to create the same directory tree within the ~/otherDir tree
find myDir -name '*.html' | cpio -pdm ~/otherdir
I don’t have a mac
find myDir -name '*.html' -print | xargs -I {} cp {} ~/otherDir
or if you can
find myDir -name '*.html' -print0 | xargs -0 -I {} cp {} ~/otherDir
as this will be safe for files with spaces in the name.
Method 5
Does OSX support -execdir for find?
find ./myDir -name "*.html" -execdir cp {} /abspath/to/otherDir ";"
Gnu/find suggests using -execdir instead of -exec for most cases.
Method 6
ls myDir/*.html | xargs -I {} cp {} ~/otherDir
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0