2

Если есть следующие проблемы: у меня есть ряд файлов, которые приходят в парах (но не всегда). Есть 2400_001.jpg и 2400??????_002.jpg. Мне нужно поменять местами _001 и _002. Поэтому я подумал, что смогу сделать это:

for f in $(find -type f -name "*_002.jpg"); do mv "${f}" "${f%_002.jpg}_003.jpg"; done
for g in $(find -type f -name "*_001.jpg"); do mv "${g}" "${g%_001.jpg}_002.jpg"; done
for h in $(find -type f -name "*_003.jpg"); do mv "${h}" "${h%_003.jpg}_001.jpg"; done

Странно, после шага 2 у меня есть * _003.jpg и * _002.jpg, которые идентичны. Что здесь происходит?

Тогда проблема становится немного сложнее: я хочу поменять местами только если оба члена пары существуют. Иногда только 2400_001.jpg существует и 2400??????_002.jpg отсутствует. Если это так, то я хочу оставить 2400?_001.jpg один.

1 ответ1

0

Попробуйте это в оболочке bash :

find -type f -name "*_001.jpg" -print0 | while read -d $'\0' f; do
  t=$(mktemp --tmpdir=$(dirname "$f"))
  [ -f "${f%_001.jpg}_002.jpg" ] && \
  mv -v "$f" "$t" && mv -v "${f%_001.jpg}_002.jpg" "$f" && mv -v "$t" "${f%_001.jpg}_002.jpg"
done

Как скрипт, он должен выглядеть так (немного более читабельно):

#!/bin/bash
find -type f -name "*_001.jpg" -print0 | while read -d $'\0' f; do
  t=$(mktemp --tmpdir=$(dirname "$f"))
  [ -f "${f%_001.jpg}_002.jpg" ] && \
    mv -v "$f" "$t" && \
    mv -v "${f%_001.jpg}_002.jpg" "$f" && \
    mv -v "$t" "${f%_001.jpg}_002.jpg"
done

Объяснение:

  • Сначала мы создаем список файлов с помощью find . Для обработки странных имен файлов используйте -print0 для разделения файлов с нулевым байтом
  • while read -d $'\0' f: чтение вывода find разделенного нулевым байтом
  • Создать временный файл
  • Проверьте, существуют ли оба файла
  • Переместить оригинал (001) в временный файл
  • Переместить 002 в 001
  • Переместить временный файл в 002

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .