0

The directory structure is as follows.

├── input
│   ├── config.ac
│   ├── dir1
│   │   ├── image2.png
│   │   └── image3.jpg
│   ├── dir2
│   └── image1.png
├── main.sh
└── output

Essentially, I am trying to run the following ./main.sh input output which I want to produce the following:

├── input
│   ├── config.ac
│   ├── dir1
│   │   ├── image2.png
│   │   └── image3.jpg
│   ├── dir2
│   └── image1.png
├── main.sh
└── output
    ├── dir1
    │   └── image2.png
    ├── dir2
    └── image1.png

After trying several thing such as find -exec, I went through it step by step. I'm trying to copy the internal directory structure of input into output while at the same time only copying .png files and nothing else. Here is what I have tried:

for DIR in $1/; do
       mkdir $2/$DIR
       cp $1/$DIR*.png $1/$DIR $2/$DIR
done

Here is my logic, the for loop will go through every directory structure in the source directory($1), it will then make the exact same directory in the destination directory($2). Now, it looks for any .png files in the current directory it is in and copies it to the exact same corresponding directory that was just created in the destination. Note, I do plan on doing some conversions to the files later on in the for loop

This doesn't seem to work at all. I get the following errors:

cp: cannot stat 'input/input/*.png': No such file or directory
cp: cannot stat 'input/input/': No such file or directory
FShiwani
  • 181
  • 1
  • 10

3 Answers3

2

Change to the directory you are copying from

Then

tar cf - .| ( cd /other directory; tar xf -)
Ed Heal
  • 59,252
  • 17
  • 87
  • 127
1

You'll be probably happy with rsync:

rsync -a --include '*/' --include '*.png' --exclude '*' input/ output

This should copy all directories AND png files. If you want to see what would be copied, add -nv options.

(See the notes on rsync versions here.)

Community
  • 1
  • 1
liborm
  • 2,634
  • 20
  • 32
  • That works, however, the output directory now has a sub folder called /input/ – FShiwani Apr 09 '17 at 17:53
  • Sorry, my bad - you need to use trailing `/` for the input - fixed in the answer. – liborm Apr 09 '17 at 17:57
  • That works! I appreciate it. I'm just curious, is it possible to do the same with my method above or perhaps using find with an -exec ? – FShiwani Apr 09 '17 at 18:05
  • I'm not a fan of bash loops (so I'm not good at using them). If I wanted to take the 'hard way', I would do something like `find input -type d | sed 's/^input/output/' | xargs mkdir -p`... – liborm Apr 09 '17 at 21:26
1

My favorite for copying directory trees (using your input/output structure):

cd input
find . | cpio -pdm ../output

Adjust the 'find' options as required.

Wayne Vosberg
  • 1,023
  • 5
  • 7