1

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

general/header.txt
scripts/test
scripts/tt

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

new/general/header.txt
new/scripts/test
new/scripts/tt

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.

1

Here is a method that only uses POSIX shell features:

find ~/dim_import/* -type f ! -name xdir -exec sh -c '
  p=${1%/*}; 
  d=${p##*/}; 
  f=${1##*/}; 
  mkdir -p new/"$d"; 
  cp "$1" new/"$d"' -- {} \;
| improve this answer | |
  • 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 '15 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 '15 at 16:59
  • @evilsoup in this case, $0 is --. – jordanm Jul 15 '15 at 18:01
0

xargs should be available. You could use:

find ~/dim_import/* -type f ! -name xdir | xargs -I {} cp {} new/{}
| improve this answer | |
  • 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 '15 at 21:17
0

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.

| improve this answer | |
  • I tried recursive copy, doesn't work how I want it. – James Jul 13 '15 at 12:45
0

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"
  fi

  # 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
| improve this answer | |

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.