5

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
----------ABC_DEF-001.jpg
----------ABC_DEF-002.jpg
------Sub-Directory ABC_GHI
----------ABC_GHI-001.jpg
----------ABC_GHI-002.jpg

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:

DIR=/var/www/html/beeinfo.org/resources/videos/
find "$DIR" -type d |
while read d;
do
    files=$(ls -t "$d" | sed -n '1h; $ { s/\n/,/g; p }')
    printf '%s,%s\n' "$files";
done

How can I fix this code?

Philippos
  • 13,237
  • 2
  • 37
  • 76
Apricot
  • 487
  • 1
  • 8
  • 15
  • 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 09 '17 at 12:09

4 Answers4

6

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

cd -- "$DIR" &&
  cp -- */*-001.jpg /destination/path
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
Philippos
  • 13,237
  • 2
  • 37
  • 76
  • This makes the most sense to me. – igal Nov 09 '17 at 15:02
  • 2
    @igal - beware of [the limitations](https://unix.stackexchange.com/q/110282) 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 09 '17 at 15:46
  • @Philippos Many thanks...this is quite intuitive and help me straight away. – Apricot Nov 13 '17 at 05:46
4

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.

αғsнιη
  • 40,939
  • 15
  • 71
  • 114
3

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.

dessert
  • 1,687
  • 14
  • 29
  • 2
    [same for `-exec` with `+` terminator as well](https://unix.stackexchange.com/questions/403486/shell-script-copy-first-file-from-multiple-folders-into-one-single-folder/403491#comment721415_403501) – αғsнιη Nov 09 '17 at 16:29
0

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/
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501