2015-10-31 1 views
0

Предположим, у меня есть файлы, вложенные в подкаталоги с потенциально повторяющимися именами файлов. Я хочу скопировать все файлы в новый каталог, но предотвратить перезапись и сохранить имена файлов (в основном).Как копировать файлы рекурсивно, не перезаписывая дубликаты имен файлов?

Следующая не работу, потому что он переписывает дублированные имена файлов:

find /SourceDir/. -type f -exec cp -pv \{\} /DestDir/ \; 

Добавление noclobber (cp -n) не помогает, потому что дубликаты просто пропускаются.

Текущая структура файла:

SourceDir 
--SubdirA 
----File1.gif 
---- ... 
----File1000.jpg 
--SubdirB 
----File1.gif 
---- ... 
----File1000.png 
... 
--SubdirZ 
----SubdirAA 
------File1.sh 
------ ... 
------File1000.jpg 

Желаемая Структура файла:

DestDir 
--File1.gif 
--File1_1.gif <-- original name was `File1.gif` but this already existed 
--File2.jpg 
--File2.gif  <-- `File2.jpg` already exists, but not `File2.gif` 
--File3.gif 
--File3_1.gif 
--File4.jpg 
--File4_1.jpg 
--File4_2.jpg <-- original name was `File4.jpg`, but `File4_1.jpg` already existed too. 
-- ... 
--File1000.png 

Я не хотите переименовать каждый файл. И я не хочу давать произвольные хэши тем, кого мне нужно дублировать. Что вы порекомендуете?

Я нахожусь на Mac, поэтому команды Linux - это честная игра.

ответ

1

Это одно решение.

#!/bin/bash 

SourceDir="."; 
DestDir="../dest"; 

cd ${SourceDir} 
find . -type f | 
while read x 
do 
    bn=`basename $x`; 
    if [ -f "${DestDir}/$bn" ] 
    then 
    for i in {1..9999} 
    do 
     if [ ! -f "${DestDir}/${bn%.*}_${i}.${bn##*.}" ] 
     then 
      echo "Next free file extension is no $i"; 
      bn="${DestDir}/${bn%.*}_${i}.${bn##*.}" 
      break; 
     fi 
    done 
    fi 
    echo "copy file $x to ${DestDir}/$bn"; 
    cp -p "$x" "${DestDir}/$bn"; 
done 

Пожалуйста, дайте мне знать, если это сработает для вас.

+0

Прохладный. Благодарю. 'If ​​[! -f ../dest/$bn] 'line возвращает' слишком много аргументов'. Можете ли вы предложить альтернативу? – Ryan

+0

Вы имели в виду команду find. вы можете изменить первую строку на ** find SourceDir -name * .gif -type f | **, чтобы получить только файлы gif –

+0

Также, как этот дескриптор дублирует имена? Я не вижу, где дубликаты добавляются '_1' (где' file.jpg' становится 'file_1.jpg', если' file.jpg' уже существует). – Ryan

Смежные вопросы