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
    Commented Nov 9, 2017 at 12:09

4 Answers 4


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
    Commented Nov 9, 2017 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. Commented Nov 9, 2017 at 15:46
  • @Philippos Many thanks...this is quite intuitive and help me straight away.
    – Apricot
    Commented Nov 13, 2017 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.


For the first regular file in numeric order of each sub directory, with zsh, you could do:

cp -- *(/e['reply=($REPLY/*(Nn.[1]))']) /path/to/destination/

For the oldest:

cp -- *(/e['reply=($REPLY/*(NOm.[1]))']) /path/to/destination/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .