Copying files to new dir structure.

I am trying to figure out a way to script copying specific files from one dir structure to another.

I have a dir structure like this:

dira/author 1/book 1/file a.epub
             /book 2/file b.epub
    /author 2/book 1/file c.epub
    /author 3/book 1/file d.epub
             /book 2/file e.epub
             /book 3/file f.epub
<etc....>

The result I am looking for is:

dirb/author 1/file a.epub
             /file b.epub
    /author 2/file c.epub
    /author 3/file d.epub
             /file e.epub
             /file f.epub
<etc....>

Currently I just use a quick script to cp the files up one level in the "dira" file structure, dupe it to "dirb" and then clean it up manually:

find . -type f -name "*.epub" |while read file
do
        cp "$file" "${file%/*}"/../
done

I could do something like this to create the new dir structure:

find . -type f -name "*.epub" -printf "%P\n" > $books
cd dir2
awk -F / '{ print $2 }' $books | xargs $DEBUG mkdir -p

but I am stumped on copying the files into that structure. :wall:

user@ubuntu:~/programs$ tree dira
dira
 author1
    book1
       filea.epub
    book2
        fileb.epub
 author2
    book1
        filec.epub
 author3
     book1
        filed.epub
     book2
        filee.epub
     book3
         filef.epub

9 directories, 6 files
user@ubuntu:~/programs$
user@ubuntu:~/programs$ cat test.sh
#! /bin/bash

find . -type f -name "*.epub" | \
while read x
do
    y=${x%/*}; y=${y%/*}; y=${y/dira/dirb}
    mkdir -p $y
    cp $x $y
done
user@ubuntu:~/programs$ ./test.sh
user@ubuntu:~/programs$ tree dirb
dirb
 author1
    filea.epub
    fileb.epub
 author2
    filec.epub
 author3
     filed.epub
     filee.epub
     filef.epub

3 directories, 6 files
user@ubuntu:~/programs$ 
2 Likes

That works! Thanks for the help!

I also came up with this as another option:

#!/bin/bash
sdir=<path>/dira
ddir=<path>/dirb

cd "$sdir"; 

IFS='\
'
for author in `ls -1`; 
do 
(mkdir "$ddir/$author"; find "$author" -type f -name "*.epub" -exec cp "{}" "$ddir/$author" \;); 
done