Ubuntu – Find, Duplicate, Rename and Copy to this folder

bash

First time poster so go easy on me haha.

Beginner linux user, starting out bash scripting and want to make a script to scan my TV Shows folder for fanart.jpg (every show has this file) create a duplicate, rename it (as I understand unix systmes do not auto rename files or allow files with same names in the one directory), and copy to a wallpaper folder.

I've read tons of articles and can not seem to find a relatively simple way of doing this.

So far all Ive got is:

cd /mnt/TV\ Shows/

find /mnt/TV\ Shows/ -name fanart.jpg

Which gives me a list of all my fanart.jpg files in their respective folders.

Ive tried a few different things after this like sed mv and cp but just cant seem to get it working.

Target folder is /mnt/Wallpapers/Slideshow/

Any help would be gratefully appreciated.

Cheers!

Best Answer

Here is example script that users find, which output is piped to a while loop:

find "/mnt/TV Shows/" -type f -name "fanart.jpg" | while IFS= read -r item; do
    NAME="${item##*/}"
    echo cp "$item" "/mnt/Wallpapers/Slideshow/${NAME%.*}-$((i++)).${NAME##*.}"
done
  • Remove echo the do the action.

  • The name of the destination file will consist of:

    ${name of source file}-$((sequential number))-${extension of source file}
    
  • The numbering will start from 0, because the variable $i has not been pre-initialized. You can put i=1; before find to start numbering from 1.


Here is more complicated script that uses the globstart option ** to make recursive search for a file within a folder. If there is a coincidence the file will be be copied to a destination folder. You can choice between different patterns of the destination file name by changing the inner (if-fi) part of the script.

#!/bin/bash

INPUT_PATH="/mnt/TV Shows"
INPUT_FILE_NAME="fanart.jpg"
OUTPUT_PATH="/mnt/Wallpapers/Slideshow"

shopt -s globstar

for item in "${INPUT_PATH}"/**; do
    # If the item is a file and its name is equal to the INPUT_FILE_NAME
    if [[ -f "$item" && "${item##*/}" == "$INPUT_FILE_NAME" ]]; then
        # Compose OUTPUT_FILE name based on the parent directory name
        INPUT_FILE_FULL_PATH="${item%/*}"
        INPUT_FILE_PARENT_DIR="${INPUT_FILE_FULL_PATH##*/}"
        OUTPUT_FILE_NAME="${INPUT_FILE_NAME%.*}-${INPUT_FILE_PARENT_DIR}.${INPUT_FILE_NAME##*.}"
        # Remove 'echo' to execute the command !!!
        echo cp "${item}" "${OUTPUT_PATH}/${OUTPUT_FILE_NAME}"
    fi
done

References:

Related Question