Copy all files with a certain extension from all subdirectories
Solution 1
--parents
is copying the directory structure, so you should get rid of that.
The way you've written this, the find
executes, and the output is put onto the command line such that cp
can't distinguish between the spaces separating the filenames, and the spaces within the filename. It's better to do something like
$ find . -name \*.xls -exec cp {} newDir \;
in which cp
is executed for each filename that find
finds, and passed the filename correctly. Here's more info on this technique.
Instead of all the above, you could use zsh and simply type
$ cp **/*.xls target_directory
zsh
can expand wildcards to include subdirectories and makes this sort of thing very easy.
Solution 2
From all of the above, I came up with this version. This version also works for me in the mac recovery terminal.
find ./ -name '*.xsl' -exec cp -prv '{}' '/path/to/targetDir/' ';'
It will look in the current directory and recursively in all of the sub directories for files with the xsl extension. It will copy them all to the target directory.
cp flags are:
- p - preserve attributes of the file
- r - recursive
- v - verbose (shows you whats being copied)
Solution 3
I had a similar problem. I solved it using:
find dir_name '*.mp3' -exec cp -vuni '{}' "../dest_dir" ";"
The '{}'
and ";"
executes the copy on each file.
Solution 4
I also had to do this myself. I did it via the --parents argument for cp:
find SOURCEPATH -name filename*.txt -exec cp --parents {} DESTPATH \;
Solution 5
find [SOURCEPATH] -type f -name '[PATTERN]' |
while read P; do cp --parents "$P" [DEST]; done
you may remove the --parents but there is a risk of collision if multiple files bear the same name.
Related videos on Youtube
![Abdel](https://i.stack.imgur.com/XiDX2.jpg?s=256&g=1)
Abdel
My research is on the genetics of complex traits and population genetics. Sometimes I use Perl, R, or bash to program something, and usually when I get stuck, the friendly users of stackoverflow are of great help :-) #SOreadytohelp
Updated on July 08, 2022Comments
-
Abdel almost 2 years
Under unix, I want to copy all files with a certain extension (all excel files) from all subdirectories to another directory. I have the following command:
cp --parents `find -name \*.xls*` /target_directory/
The problems with this command are:
It copies the directory structure as well, and I only want the files (so all files should end up in /target_directory/)
It does not copy files with spaces in the filenames (which are quite a few)
Any solutions for these problems?
-
fedorqui over 11 yearsWhat about
find... exec mv
? -
jww almost 6 yearsPossible duplicate of Move files to directories based on extension
-
ingernet almost 4 yearsthis question actually answered the question i came here to ask. thank you!
-
Abdel over 11 yearsSorry for my bash illiteracy, but what do you mean by "bin"?
-
Brian Agnew over 11 yearsYes. 'bin it' means to throw it away. Now amended :-)
-
Abdel over 11 yearsHaha got it! Tnx! It doesn't quite work for me yet unfortunately... The "cp */.xls target_directory" for some reason does not copy all the files (it only looks 1 subdirectory deep, and does not copy files in subdirectories of subdirectories). The "find . -name *.xls* -exec cp ..." command gives me the message "find: missing argument to `-exec'"
-
pynexj over 11 years
Bash
4.0+ andksh93
also supports**
. For bash, useshopt -s globstar
to enable it. For ksh, it'sset -G
orset -o globstar
. -
Kevin Suttle almost 9 yearsHow would you do this in bash 3.2?
-
Taywee almost 8 yearsThat exec is technically less efficient than passing into xargs, which will do it all in as few cp calls as possible:
find . -name '*.xls' -print0 | xargs -0 cp -t destdir
-
Brian Agnew almost 8 years@Taywee - yes. I didn't want to confuse matters, however, and simply focus on the particular issue. A further efficiency measure is always good
-
Taywee almost 8 years@BrianAgnew Oh, I'm sure, just good to have extra information in the comments for wayward googlers.
-
Plummer over 7 yearsThis is the same as what I had to do when SSH'd into Bluehost.
-
lal about 7 yearsUsing this
zsh cp
variant for serching within a directory:cp -pPR **en.lproj/*.strings SignLocalization
. -
b005t3r over 6 yearsIt does NOT preserver subdirs.
-
TheWhitestOfFangs over 5 years@BrianAgnew This copies the files indeed, however it does not retain the directory structure if used recursively. Is there a quick way of making it retain the directory tree from the source?
-
Datbates about 5 yearsThanks! Wanted to grab all images and this expansion with a regex worked really nicely find -E source -iregex ".*\.(jpg|jpeg|tiff|png|mpeg|mp4|m4v|avi|mov|mts|m2ts|vob)" -exec cp {} destination \; (mac os)
-
Madivad almost 5 years@b005t3r that is by design, it is not supposed to. That was the whole intent of the OP's question. He wanted all files from subdirectories copied into one directory without subdirs
-
Matthew Dean about 4 yearsIs there a way to modify this to preserve sub-directories?
-
Ivankovich almost 4 yearsnote that the destination directory must already exist, otherwise this script will simply copy and rename the file to the directory name you supply.
-
drmercer almost 4 years@MatthewDean You can use the
--parents
flag tocp
to accomplish that. Something likefind ./ -name '*.xsl' -exec cp --parents {} targetDir/ ';'
-
Jordan McBain over 2 yearsWhat do the braces do? and why the ';'