2

I'm trying to copy directory structure from src_dir to dst_dir.

On my CentOS 6.4 Linux Bash this command works fine.

[localhost]$ find src_dir   
src_dir     
src_dir/dir2    
src_dir/dir2/dir4   
src_dir/dir1   
src_dir/dir1/test.txt   
src_dir/dir1/dir3

[localhost]$ find src_dir -type d -exec mkdir -p "dst_dir/{}" \;   

[localhost]$ find dst_dir    
dst_dir/src_dir    
dst_dir/src_dir/dir2    
dst_dir/src_dir/dir1    
dst_dir/src_dir/dir1/dir3  

But, when I'm doing the same command in IBM AIX 6.1, I got this output

[aix61:/data]find dst_dir    
dst_dir    
dst_dir/{} 

Maybe the 'find' command parameter {} replacement is somewhat different in AIX.
But I don't know how to solve it. Any advice would be helpful.

3

Yes, that syntax is not POSIX. Only a standalone {} (on its own argument) is guaranteed to be expanded.

Use:

find src_dir -type d -exec sh -c 'for dir do
  mkdir -p "dst_dir/$dir"; done' sh {} +

Or to avoid running one mkdir per directory:

find src_dir -type d -exec sh -c 'for dir do
  set -- "$@" "dst_dir/$dir"; shift; done
  mkdir -p "$@"' sh {} +

(though there's a risk of reaching the "arg list too large" condition).

Note that it would create dst_dir/src_dir/x/y.... If you wanted dst_dir/x/y..., you'd do:

find src_dir -type d -exec sh -c 'for dir do
  set -- "$@" "dst_dir${dir#src_dir}"; shift; done
  mkdir -p "$@"' sh {} +

Another option, if you can guarantee that directory paths don't contain newline characters would be to use pax:

find src_dir -type d | pax -rw dst_dir

That would allow you do also copy the directories metadata like ownership and permissions (with -pe)

To remove the leading src_dir component in the destination:

find src_dir -path '*/*' -type d | pax -'s@^src_dir/@@' -rw dst_dir

Or:

(cd src_dir && find . -type d | pax -rw ../dst_dir)

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.