Jon McPherson
Jon McPherson

Reputation: 2535

Unable to use dirname within subshell in find command

I am trying to make a small script that can move all files from one directory to another, and I figured using find would be the best solution. However, I have run into a problem of using subshells for the 'dirname' value in creating the target directory paths. This does not work because {} evaluates to '.' (a single dot) when inside a subshell. As seen in my script bellow, the -exec mkdir -p $toDir/$(dirname {}) \; portion of the find command is what does not work. I want to create all of the target directories needed to move the files, but I cannot use dirname in a subshell to get only the directory path. Here is the script:

#!/bin/bash

# directory containting files to deploy relative to this script
fromDir=../deploy
# directory where the files should be moved to relative to this script
toDir=../main

if [ -d "$fromDir" ]; then
    if [ -d "$toDir" ]; then
        toDir=$(cd $toDir; pwd)
        cd $fromDir
        find * -type f -exec echo "Moving file [$(pwd)/{}] to [$toDir/{}]" \; -exec mkdir -p $toDir/$(dirname {}) \; -exec mv {} $toDir/{} \;
    else
        echo "A directory named '$toDir' does not exist relative to this script"
    fi
else
    echo "A directory named '$fromDir' does not exist relative to this script" 
fi

I know that you can us -exec sh -c 'echo $(dirname {})' \;, but with this, I would then not be able to use the $toDir variable.

Can anyone help me figure out a solution to this problem?

Upvotes: 1

Views: 388

Answers (1)

DouglasDD
DouglasDD

Reputation: 425

Since you appear to be re-creating all the files and directories, try the tar trick:

mkdir $toDir
cd $fromDir
tar -cf - . | ( cd $toDir ; tar -xvf - )

Upvotes: 1

Related Questions