I am trying to copy files and the directory it is in to another location. I can find the path like this:

find ~/dim_import/* -type f ! -name xdir | cut -d '/' -f 5-10

which outputs


How do I copy these to another location? For example the new location would be


The issue is that there are more directories that are empty and I do not want to copy those, only the directories that have files in them and the files themselves.

NOTE: not using bash, using sh.


4 Answers 4


Here is a method that only uses POSIX shell features:

find ~/dim_import/* -type f ! -name xdir -exec sh -c '
  mkdir -p new/"$d"; 
  cp "$1" new/"$d"' -- {} \;
  • This fails. It outputs: cp: cannot access : No such file or directory cp: cannot access : No such file or directory cp: cannot access : No such file or directory So the mkdir command isn't working
    – James
    Jul 13, 2015 at 13:46
  • I'm think the problem here is that you need to use 0 for every 1 ised in the answer ($0 in ash -c command is equivalent to $1 in a shell script. I have no idea why that's the case).
    – evilsoup
    Jul 15, 2015 at 16:59
  • @evilsoup in this case, $0 is --.
    – jordanm
    Jul 15, 2015 at 18:01

xargs should be available. You could use:

find ~/dim_import/* -type f ! -name xdir | xargs -I {} cp {} new/{}
  • This will copy to new/$HOME/dim_import/general/ and will only work if that path already exists. He just wants new/general.
    – jordanm
    Jul 10, 2015 at 21:17

Since you already know how to filter the files, then use recursive copy: cp -R

Or you could just use rsync with --prune-empty-dirs option.

rsync --exclude='*xdir*' --prune-empty-dirs ~/dim_import ~/new

Note: If you don't use trailing slash from source (like above's example) dim_import is also copied.

  • I tried recursive copy, doesn't work how I want it.
    – James
    Jul 13, 2015 at 12:45

I ended up just writing to a file:

find ~/dim_import/* -type f ! -name xdir | cut -d '/' -f 5-6 > files

and then looping through the "files" file and creating the directories from that and then copying the files there.

while read line; do
  fileDir=`echo "$line" | cut -d '/' -f 1`    # get folder name
  fileName=`echo "$line" | cut -d '/' -f 2`   # get file name
  cd ~/"sr${srNum}"                           # go to SR folder

  # If proper directory doesn't exist, create
  if [ ! -d "$fileDir" ]; then 
    mkdir "$fileDir"

  # Copy file to respected directory
  cd $ROOT                                        # go back to dim_import
  cp "$fileDir/$fileName" ~/"sr$srNum/$fileDir"   # copy file to fileDir folder
  cd ~/"sr$srNum/$fileDir"                        # go to fileDir
  chmod u+w "$fileName"                  # mod the file for write access for changes
  cd $ROOT                                        # go back to dim_import
done < files

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.