Search code examples
linuxshellunixfindxargs

Shell - Recursively find sub-directories and copy containing files to another directory


I have got the following directory-/file structure:

/test
     /dir_a
         /dir_pic
             car.jpg
             train.jpg
             thumbs.db
     /dir_b
         /dir_pic
             car.jpg
             plane.jpg
             boat.jpg
     /dir_c
         /dir_pic
             ship.jpg
             space_shuttle.jpg

I would like to copy the files creating the following structure:

 /test2
     /c
         /car
             car.jpg
     /b
         /boat
             boat.jpg
     /p
         /plane
             plane.jpg
     /s
         /ship
             ship.jpg
         /space shuttle
             space shuttle.jpg
     /t
         /train
             train.jpg

I created the sub-directories with for i in {a..z}; do mkdir ordner${i}; done, but I don't know how to create the sub-directories and how to copy the files. I tried something like find /test/ -type d -name ".dir_pic" | xargs -0 -I%%% cp %%%/${i}*.jpg /test2/, but that doesn't work. Apart from that for-loops don't work, especially when the path contains blanks ?

As my Linux-knowledge is quite limited I would kindly ask for your help how to realize this (Ubuntu 16.04 LTS).


Solution

  • bash solution:

    #!/bin/bash
    
    dest_dir="/test2"         # destination directory
    
    for f in $(find /test/ -type f -path "*/dir_pic/*.jpg"); do 
        fn="${f##*/}"         # filename (basename)
        parent_d="${fn:0:1}"  # parent directory
        child_d="${fn%.*}"    # child directory
    
        if [[ ! -d "$dest_dir/$parent_d/$child_d" ]]; then
            mkdir -p "$dest_dir/$parent_d/$child_d"
            cp "$f" "$dest_dir/$parent_d/$child_d/$fn" 
        fi
    done
    

    Viewing results:

    $ tree /test2
    |-- b
    |   `-- boat
    |       `-- boat.jpg
    |-- c
    |   `-- car
    |       `-- car.jpg
    |-- p
    |   `-- plane
    |       `-- plane.jpg
    |-- s
    |   |-- ship
    |   |   `-- ship.jpg
    |   `-- space_shuttle
    |       `-- space_shuttle.jpg
    |-- t
    |   `-- train
    |       `-- train.jpg