0

This is the folder structure:

/home/user/Pictures/Vacation/Italy/Rome/photo.front.001.jpg

Within the folder Rome I have many other photos, but I'm only interested in the ones that have "front" in the filename. Of these I should make a copy and call it "fanart.jpg" (still in the Rome folder).

I'd like to do this for all the folders stored in Italy parent folder.

I've been trying to use find to search for this pictures, but then I'm not able to make a copy with a different name.

Do you have an idea on how to solve this?

2

You should be able to use -execdir to make a copy relative to the directory of the found file(s) e.g.

find Italy -name '*.front.*' -execdir cp -- {} 'fanart.jpg' \;

Example: given

$ tree Italy/
Italy/
├── Florence
│   ├── photo.back.001.jpg
│   ├── photo.back.002.jpg
│   ├── photo.back.003.jpg
│   ├── photo.front.001.jpg
│   ├── photo.front.002.jpg
│   └── photo.front.003.jpg
├── Naples
│   ├── photo.back.001.jpg
│   ├── photo.back.002.jpg
│   ├── photo.back.003.jpg
│   ├── photo.front.001.jpg
│   ├── photo.front.002.jpg
│   └── photo.front.003.jpg
└── Rome
    ├── photo.back.001.jpg
    ├── photo.back.002.jpg
    ├── photo.back.003.jpg
    ├── photo.front.001.jpg
    ├── photo.front.002.jpg
    └── photo.front.003.jpg

3 directories, 18 files

Then

$ find Italy -name '*.front.*' -execdir cp -v -- {} 'fanart.jpg' \;
‘./photo.front.001.jpg’ -> ‘fanart.jpg’
‘./photo.front.003.jpg’ -> ‘fanart.jpg’
‘./photo.front.002.jpg’ -> ‘fanart.jpg’
‘./photo.front.001.jpg’ -> ‘fanart.jpg’
‘./photo.front.003.jpg’ -> ‘fanart.jpg’
‘./photo.front.002.jpg’ -> ‘fanart.jpg’
‘./photo.front.001.jpg’ -> ‘fanart.jpg’
‘./photo.front.003.jpg’ -> ‘fanart.jpg’
‘./photo.front.002.jpg’ -> ‘fanart.jpg’

(note that if there are multiple files matching the *.front.* pattern, the copy gets successively overwritten - if that's not what you want, add -n or --no-clobber), resulting in

$ tree Italy/
Italy/
├── Florence
│   ├── fanart.jpg
│   ├── photo.back.001.jpg
│   ├── photo.back.002.jpg
│   ├── photo.back.003.jpg
│   ├── photo.front.001.jpg
│   ├── photo.front.002.jpg
│   └── photo.front.003.jpg
├── Naples
│   ├── fanart.jpg
│   ├── photo.back.001.jpg
│   ├── photo.back.002.jpg
│   ├── photo.back.003.jpg
│   ├── photo.front.001.jpg
│   ├── photo.front.002.jpg
│   └── photo.front.003.jpg
└── Rome
    ├── fanart.jpg
    ├── photo.back.001.jpg
    ├── photo.back.002.jpg
    ├── photo.back.003.jpg
    ├── photo.front.001.jpg
    ├── photo.front.002.jpg
    └── photo.front.003.jpg

If your system's version of find doesn't support -execdir an alternate way would be to remove the filename portion of the full pathname - for example using POSIX parameter expansion of the form "${var%/*}" - and replace it with the newname in a little inline shell command sh -c

find Italy -name '*.front.*' -exec sh -c 'cp -v -- "$1" "${1%/*}/fanart.jpg"' sh {} \;
0

Do you have a requirement to use find? For things like that, I find loops to be more appropriate:

$ cd /home/user/Pictures/Vacation/Italy
$ for directory in *; do \
    cd "$directory" && \
    for file in *front*; do \
        cp --force "$file" fanart.jpg; \
    done; \
    cd /home/user/Pictures/Vacation/Italy; \
  done

Essentially, this just goes through subdirectories of "Italy" and for each of them, copies files with "Front" in their name to a file named "fanart.jpg" (overwriting things, because the destination filename is constant.)

  • Thank you for the answer! I don't have a requirement to use find, but when executing the script you made it gives me: line 8: syntax error: unexpected end of file. I'm not very familiar with code. – Issam2204 Jun 19 '16 at 13:10
  • Ah, sorry—forgot a semicolon after "fanart.jpg". Should work now. – Alexander Batischev Jun 19 '16 at 13:29

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.