Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have created the following script that move old days files as defined from source directory to destination directory. It is working perfectly.

#!/bin/bash

echo "Enter Your Source Directory"
read soure

echo "Enter Your Destination Directory"
read destination 

echo "Enter Days"
read days



 find "$soure" -type f -mtime "-$days" -exec mv {} "$destination" \;

  echo "Files which were $days Days old moved from $soure to $destination"

This script moves files great, It also move files of source subdirectory, but it doesn't create subdirectory into destination directory. I want to implement this additional feature in it.

with example

/home/ketan     : source directory

/home/ketan/hex : source subdirectory

/home/maxi      : destination directory

When I run this script , it also move hex's files in maxi directory, but I need that same hex should be created into maxi directory and move its files in same hex there.

share|improve this question

3 Answers 3

up vote 0 down vote accepted

Instead of running mv /home/ketan/hex/foo /home/maxi, you'll need to vary the target directory based on the path produced by find. This is easier if you change to the source directory first and run find .. Now you can merely prepend the destination directory to each item produced by find. You'll need to run a shell in the find … -exec command to perform the concatenation, and to create the target directory if necessary.

destination=$(cd -- "$destination" && pwd) # make it an absolute path
cd -- "$source" &&
find . -type f -mtime "-$days" -exec sh -c '
  mkdir -p "$0/${1%/*}"
  mv "$1" "$0/$1"
' "$destination" {} \;

Note that to avoid quoting issues if $destination contains special characters, you can't just substitute it inside the shell script. You can export it to the environment so that it reaches the inner shell, or you can pass it as an argument (that's what I did). You might save a bit of execution time by grouping sh calls:

destination=$(cd -- "$destination" && pwd) # make it an absolute path
cd -- "$source" &&
find . -type f -mtime "-$days" -exec sh -c '
  for x do
    mkdir -p "$0/${x%/*}"
    mv "$x" "$0/$x"
  done
' "$destination" {} +

Alternatively, in zsh, you can use the zmv function, and the . and m glob qualifiers to only match regular files in the right date range. You'll need to pass an alternate mv function that first creates the target directory if necessary.

autoload -U zmv
mkdir_mv () {
  mkdir -p -- $3:h
  mv -- $2 $3
}
zmv -Qw -p mkdir_mv $source/'**/*(.m-'$days')' '$destination/$1$2'
share|improve this answer

You can do this by appending the absolute path of the file returned by find to your destination path:

find "$soure" -type f -mtime "-$days" -print0 | xargs -0 -I {} sh -c '
    file="{}"
    destination="'"$destination"'"
    mkdir -p "$destination/${file%/*}"
    mv "$file" "$destination/$file"'
share|improve this answer
    
Chris now its moves whole home into maxi –  K.K Patel Dec 21 '12 at 15:11
    
@K.KPatel No, it doesn't. It merely keeps your directory structure. –  Chris Down Dec 21 '12 at 17:26
    
This breaks if $destination contains special characters, because it undergoes expansion in the inner shell. Maybe you meant destination='\'"$destination"\''? That still breaks on '. Also, this creates files such as /home/maxi/home/ketan/hex/foo instead of /home/maxi/hex/foo. –  Gilles Dec 22 '12 at 0:03

you could do it using two instances of find(1)

There's always cpio(1)

(cd "$soure" && find … | cpio -pdVmu "$destination")

Check the arguments for cpio. The ones I gave

share|improve this answer
    
This will break on any filenames with whitespace. –  Chris Down Dec 21 '12 at 17:26
    
This copies files instead of moving them. –  Gilles Dec 22 '12 at 0:01
    
May not be a perfect answer, but it helped me to move files preserving paths in a more or less straight forward manner (I have enough space to copy the files then delete). Upvoted –  AhHatem Apr 27 at 10:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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