yaya hoho
yaya hoho

Reputation: 103

Linux find and copy files with same name to destination folder do not overwrite

I want to find and copy all files with *.jpg in one folder includes its sub folder to another folder I use

find /tempL/6453/ -name "*.jpg" |  xargs  -I  '{}' cp {} /tempL/;

but it overwrite files with same name

for example in /tempL/6453/, there are test (1).jpg test (2).jpg and folder 1, in /tempL/6453/1/, there are also have files with the same name test (1).jpg test (2).jpg

If I use the above command, there are only two files test (1).jpg test (2).jpg in /tempL/, it can not copy all files to /tempL/.

What I want is to copy all files to /tempL/, when there are same file name, just rename them, how to?

Upvotes: 9

Views: 11345

Answers (3)

Eduardo Lucio
Eduardo Lucio

Reputation: 2447

Below is a tested and working implementation.


MODEL

#!/bin/bash

find "<SOME_FOLDER_PATH>" -type f "<SOME_FIND_ARG>" -exec sh -c '
    DESTINATION_DIR="<SOME_DESTINY_FOLDER>"
    for FOUND_FILE do
        BASE_NAME=$(basename "$FOUND_FILE")
        if [ -f "$DESTINATION_DIR/$BASE_NAME" ]; then
            cp "$FOUND_FILE" "$DESTINATION_DIR/$BASE_NAME-$(uuidgen | cut -d "-" -f 2)"
        else
            cp "$FOUND_FILE" "$DESTINATION_DIR/$BASE_NAME"
        fi
    done
' bash {} +

EXAMPLE

#!/bin/bash

find "/some/folder/path/" -type f -iname "*some_find_arg*" -exec sh -c '
    DESTINATION_DIR="/some/destiny/folder"
    for FOUND_FILE do
        BASE_NAME=$(basename "$FOUND_FILE")
        if [ -f "$DESTINATION_DIR/$BASE_NAME" ]; then
            cp "$FOUND_FILE" "$DESTINATION_DIR/$BASE_NAME-$(uuidgen | cut -d "-" -f 2)"
        else
            cp "$FOUND_FILE" "$DESTINATION_DIR/$BASE_NAME"
        fi
    done
' bash {} +

EXTRA: Remove duplicate files...

EXAMPLE

cd "/some/destiny/folder"
fdupes -rdN ./

# r - recursive
# d - preserve first file, delete other dupes
# N - run silently (no prompt)

Upvotes: 0

SergioAraujo
SergioAraujo

Reputation: 11800

Install "GNU parallel" and use:

find /tempL/6453/ -name "*.jpg" | parallel 'cp {} ./dest-dir/`stat -c%i {}`_{/}'

{/}  ................. gets filename with no full path

I think the same approach should be possible with xargs, but learning about parallel was amazing for me, it gives us many beautiful solutions.

I recommend using echo before cp in order to test your command

Upvotes: 2

gzh
gzh

Reputation: 3596

What I want is to copy all files to /tempL/, when there are same file name, just rename them, how to?

1) If you only do not what overwrite cp --backup will give you a backup for existing file, with --suffix option of cp, you can also specify the suffix to be used for backup.

2) --parents option of cpwill keep directory tree, i.e. files in folder 1 will be copy to new created 1 folder.

3) If you want to customize your rename processing, you can not use cp command only. write script for it and call it to process the result of find

Upvotes: 7

Related Questions