How can I copy all of the files that are found in subfolders within one directory, to another directory? I am having trouble with this because some of the end files are in more folders than others.

I know of people using find so you can find certain endings to file names like .txt, but my files have no file type

I currently have cp -r cs/cs/201*sp/. all/

The problem is, I have two folders that contain files that need to be copied which are a subset of 201*sp/

Currently, it copies all of the right items that are not in those two folders, but then it copies those folders themselves, when I need it to just copy their contents.

  • You can pass the -type f flag to find (i.e. find ./ -type f) and it will find ONLY files...that being said, how comfortable are you with shell scripts as this could be attained with one? – txtechhelp Feb 16 '14 at 1:12
  • I need to copy them though, not just find them. @txtechhelp – blurble Feb 16 '14 at 1:48
  • Which is why I asked if you were comfortable with shell scripts, mixing find with some other commands can yield you that result...if you're not comfortable with shell scripting then there might be other options – txtechhelp Feb 16 '14 at 1:49
  • Ah okay, I'm just now learning them. – blurble Feb 16 '14 at 1:51
  • stackoverflow.com/questions/4264529/… <- navigate subdirs via shell script (for a reference) – txtechhelp Feb 16 '14 at 1:54

find cs/cs/201*sp/ -type f -exec cp {} all/ \;

  • It might be a good idea to edit your answer to explain how the command works. – Heptite Feb 16 '14 at 9:21

If I understand what you need is a way to look within a folder, and all subfolders of that folder, and copy any files found into a different "destination" folder, without creating any subfolders in the "destination" folder.

So if you have a fileset like this:


And you are copying the files to the folder "../destfolder". Then, after the files are copied, the "../destfolder" will contain:


and "../destfolder" will contain none of the subfolders from "folderA" or "folderB".

You do this by changing to the directory that you want to copy the files from, and then run this from the command prompt:

d="../destfolder";for f in $(find -type f -exec echo {} \;); do b=$(echo $f|sed -r 's!^.*/([^/]+)!\1!'); echo cp -p "$f" "$d/$b" ;done

Before you "run" this command, you will need to substitute your actual destination folder in place of "../destfolder"

This will display a list of cp commands, but will not actually copy any files. It should look like this:

cp -p folderA/file1 ../destfolder/file1
cp -p folderA/subfolderC/file2 ../destfolder/file2
cp -p folderA/subfolderC/subD/file3 ../destfolder/file3
cp -p folderA/subfolderC/subE/file4 ../destfolder/file4
cp -p folderB/subfolderF/file5 ../destfolder/file5
cp -p folderB/subfolderG/subH/file6 ../destfolder/file6
cp -p folderB/subfolderG/subI/file7 ../destfolder/file7

Once you are confident the correct files will be copied, you can run the command again, but remove "echo" from the part of the command that's like: "echo cp -p..."

So the command that will copy the files will look like:

d="../destfolder";for f in $(find -type f -exec echo {} \;); do b=$(echo $f|sed -r 's!^.*/([^/]+)!\1!'); cp -p "$f" "$d/$b" ;done

Remember that before you "run" this command, you will need to substitute your actual destination folder in place of "../destfolder"

If you want this as a shell script, it would look like this:



for f in $(find -type f -exec echo {} \;); do 
    b=$(echo $f|sed -r 's!^.*/([^/]+)!\1!')
    echo cp -p "$f" "$d/$b"

If this is not exactly what you need, then let me know and I'll have another look at it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.