1

I have a directory of more than one million images, categorized according to the place the image was captured. Now theses places are again sorted alphabetically into folders. For example,

--- Images
        |____ a
        |     |___ airfield
        |     |___ alley
        |  
        |____ b
              |___ bank
                      |__ bank-00001.jpg
                      |__ bank-00002.jpg
                             .
                             .
                             .

How can I copy the first 100 files from each place subdirectory such as airfield, alley, bank etc. to a different folder ?

I have tried:

find /Source/Directory/path -type f  -print | tail -100 | xargs -J % cp    % /Destination/Diretory/path  

but I am guessing it overwrote the images, because only the last 100 images of the last subfolder were copied.

My bash version

GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
Copyright (C) 2007 Free Software Foundation, Inc.

2 Answers2

0

Assuming you want them all on the same destination and all the files are named the way you have represented it:

               ...
                  |__ bank-00001.jpg
                  |__ bank-00002.jpg

You can simplify the problem by doing this:

For versions of bash equal or above 4.0:

for i in {00000001...00000100}; do
    find /path/to/Images -maxdepth 3 -mindepth 1 -type f -name "*_$i.jpg" -exec cp {} /destination/path \;
done

This way you copy all the first 100 images on every sub-subfolder, based on their name.

For versions of bash prior to 4.0:

for i in $(seq -f '%08g' 1 100)
do
    find /path/to/Images -maxdepth 3 -mindepth 1 -type f -name "*_$i.jpg" -exec cp {} /destination/path \;
done

How to zero pad a sequence of integers in bash so that all have the same width?

M. Becerra
  • 639
  • 6
  • 21
  • My apologies, the images are named as "airfield_00000001.jpg" , "airfield_00000002.jpg" and so on. I modified the script you provided to reflect that, but I must have made an error somewhere, as the script executes for a while but the files are not copied. The modified script is `for i in {001...100}; do find /Users/Ynapolean/Desktop/data_256 -maxdepth 3 -mindepth 1 -type f -name "*_00000$i.jpg" -exec cp {} /Users/Ynapolean/Desktop/MITdata \; done` – Yeshwanth Napolean Dec 21 '17 at 15:42
  • Thank you for the prompt reply. I used the updated script, I still have the same issue. The script runs but does not copy the files to the new directory. – Yeshwanth Napolean Dec 21 '17 at 15:57
0

Can you try something like this:

#!/bin/bash
for files in $(find . -type f | sed -r 's/(.*\/).*$/\1/g' | uniq); 
do 
    find ${files} -type f | head -n100 | tr '\n' '\0' | xargs -0 cp /path/where/to/copy; 
done

Im not sure if it's correctly, have no linux-terminal near. The logic is: 1) Find uniq full paths to your files. 2) Run in loop, search files in each directory, get with head -n100 first 100 files, copy them with xargs

Viktor Khilin
  • 1,760
  • 9
  • 21