Создайте символическую ссылку рекурсивно, если файл 1.JPG существует, переименуйте его в 1A.JPG

У меня есть сценарий оболочки для создания символических ссылок всех моих фотографий с одного года. Фотографии находятся на разных камерах и находятся в подкаталогах.

f=$(pwd); export f; q="2015/"; z="2015_Links/"; find $q/. \( -name "*.CR2" -o -name "*.JPG" \) -execdir sh -c 'ln -s "$PWD"/$(basename {}) "$f"/"$z"/Link_$(basename {})' {} \; 

Некоторые фотографии имеют одинаковое имя файла, что вызывает ошибку:

 ln: failed to create symbolic link '2015_Links/Link_IMG_1588.CR2': File exists 

В этом случае я бы хотел переименовать эти существующие файлы. Например, Link_IMG_1588.CR2Link_IMG_1588A.CR2 .

2 Solutions collect form web for “Создайте символическую ссылку рекурсивно, если файл 1.JPG существует, переименуйте его в 1A.JPG”

Я нашел другое решение проблемы.

Мне удалось переименовать мои фотографии (с помощью find и exiv2 ) с разных камер, чтобы каждое имя файла было уникальным (IMG number + Date):

 find 2015/. \( -name "*.CR2" -o -name "*.JPG" \) -execdir sh -c 'exiv2 -r':basename:_%Y%m%d_%H_%M_%S' rename $(basename {})' {} \; 

Стратегия:

  • Проверьте, существует ли идеальное имя целевого файла.
  • Если да, попробуйте добавить числовые суффиксы -1 , -2 и т. Д.

Дополнительные улучшения:

  • Используйте -exec … {} + вместо -execdir … {} \; для небольшого улучшения производительности. Фактически вам не нужен -execdir поскольку вы создаете абсолютные ссылки.
  • Используйте $x (или $1 если вы придерживаетесь … {} \; ) вместо {} во внутренней оболочке. Никогда не используйте {} внутри фрагмента оболочки на find -exec : это вставляет имя файла непосредственно в сценарий оболочки, поэтому он анализируется как синтаксис оболочки, который разбивается, если имя файла содержит любой символ, который имеет особое значение в синтаксисе оболочки. Всегда передавайте {} в качестве отдельного параметра.

Код (непроверенный):

 find "$q/." \( -name "*.CR2" -o -name "*.JPG" \) -exec sh -c ' for x; do base=$0/Link_${x##*/}; base=${base%.*}; ext=${x##*.} if [ -e "$target.$ext" ]; then suffix=1; while [ -e "${base}-$suffix.$ext"; do suffix=$((suffix+1)); done fi ln -s -- "$PWD/${x##*/}" "$target" done ' "$PWD/$z" {} + 
Linux и Unix - лучшая ОС в мире.