In a directory, I have hundreds of sub-directories. Each sub-directory has hundreds of jpg pictures. If the folder is called "ABC_DEF", the files inside the folder will be called "ABC_DEF-001.jpg", "ABC_DEF-002.jpg", so on and so forth.

For example:

---Main Directory
------Sub-Directory ABC_DEF
------Sub-Directory ABC_GHI

From each of the sub-directory I want to copy only the first file, e.g., the file with the extension -001.jpg - to a common destination folder called DESTDIR.

I have changed the code given here to suit my use case. However, it always prints the first directory along with the filenames and I am not able to copy the files to the desired destination. The following is the code:

find "$DIR" -type d |
while read d;
    files=$(ls -t "$d" | sed -n '1h; $ { s/\n/,/g; p }')
    printf '%s,%s\n' "$files";

How can I fix this code?

  • The other question had a more difficult task because they didn't know anything about the name of the first file and needed to combine it with the last file. Unfortunally the answer didn't explain the sed script, so you didn't know how to adapt it. Your case it much simpler and you don't need that stuff. – Philippos Nov 9 '17 at 12:09

Why find when all files are in directories of the same depth?

cd "$DIR"
cp */*-001.jpg /destination/path
  • This makes the most sense to me. – igal Nov 9 '17 at 15:02
  • 2
    @igal - beware of the limitations of this solution though... Per OP, that glob will expand to only some hundreds of file names but still, it's something to keep in mind. – don_crissti Nov 9 '17 at 15:46
  • @Philippos Many thanks...this is quite intuitive and help me straight away. – Apricot Nov 13 '17 at 5:46

This is easy to do with find only if you supposed to pick the first file which is ending with -001.jpg pattern and only one in each sub-directory, so the command would be:

find . -name "*-001.jpg" -execdir echo cp -v {} /path/to/dest/ \;

Note: remove the echo for dry run once the result was what you expected.


You can use find -exec {} + to get a list of the files and call cp just once:

find /path/to/main/dir -name "*-001.jpg" -exec cp -t /path/to/dest/dir/ {} +

To test what it does first, replace cp with echo cp.


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.