Форум русскоязычного сообщества Ubuntu


Автор Тема: Как подобрать суффикс для переименования в rsync -ab --suffix= ?  (Прочитано 806 раз)

0 Пользователей и 1 Гость просматривают эту тему.

adawdp

  • Автор темы
  • Гость
2016 Aug 14; 03:35 PM; Oakville, ON, Canada.

— Есть необходимость собрать (скопировать) в одну директорию все файлы pdf из другой директории с поддиректориями.
— Делаю так:
Код: Bash
  1. find . -iname "*.pdf" -type f -print0 | xargs -0 -I '{}' /usr/bin/rsync -ab --suffix=_`date +%Y%b%d%H%M%S%N` "{}" /home/fjf/16Aug14
— Но если файл с одним и тем же именем повторяется в исходной директории более двух раз то естественно происходит переписывание  :'( … Быстро это всё работает или время назначается для всех переименованных файлов одно и то же.
— Какой-то другой суффикс наверное надо типа счётчика что ли, я не программист быстро придумать ничего не могу, подскажите что можно использовать вместо даты?

Punko

  • Автор темы
  • Гость
adawdp, может быть, подойдёт время? Или дата + случайное число?

Вообще, мне кажется это в разработку надо - быстрее ответят. Перенесу.

adawdp

  • Автор темы
  • Гость
2016 Aug 14; 08:27 PM

Punko, время не получается даже с долями секунды …
(Нажмите, чтобы показать/скрыть)
— Скорее всего время вычисляется один раз и не подставляется к каждому файлу новое…
— Экспериментирую 5 директорий по 10 файлов с одинаковыми именами. В итоге «собирается» только 21 файл, т.е. происходит замена.
— Я, конечно, выход нашёл но в несколько ступеней, а хотелось бы иметь решение на будущее из одной команды.

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 1967
    • Просмотр профиля
Код: Bash
  1. SRC_DIR=''
  2. DEST_DIR=''
  3.  
  4. IFS=$'\n'
  5. for F in $(find "$SRC_DIR" -type f -iname "*.pdf")
  6. do
  7.         N=2
  8.         D="${F%/*}"
  9.         F="${F##*/}"
  10.         B="${F%.*}"
  11.         EXT="${F##*.}"
  12.         DEST_F="${B}.${EXT}"
  13.         while [ -f "$DEST_DIR/$DEST_F" ]
  14.         do
  15.                 DEST_F="${B}_${N}.${EXT}"
  16.                 ((N+=1))
  17.         done
  18.         mv "$D/$F" "$DEST_DIR/$DEST_F"
  19. done
оно?
« Последнее редактирование: 15 Август 2016, 06:54:27 от renzrv »

adawdp

  • Автор темы
  • Гость
2016 Aug 14; 10:39 PM

— Спасибо, renzrv, возможно и ОНО, но пока не сработало :)!
— Оформил скриптом:
(Нажмите, чтобы показать/скрыть)
— Запускаю скрипт получаю вот такое:
(Нажмите, чтобы показать/скрыть)
— Возможно где-то ошибка я попробую поискать сам, но не уверен, что получится :)!

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 1967
    • Просмотр профиля
Исправил.

adawdp

  • Автор темы
  • Гость
2016 Aug 14; 11:19 PM

— Тоже, возможно где-то ошибка…
(Нажмите, чтобы показать/скрыть)

— Спасибо, до нашего завтра :)!

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 1967
    • Просмотр профиля
adawdp, Теперь проверил, исправил)

adawdp

  • Автор темы
  • Гость
2016 Aug 15; 07:44 AM

Renzrv, спасибо, это работает!
(Нажмите, чтобы показать/скрыть)
— Всё остальное можно сделать путём модификации этого скрипта.

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 1967
    • Просмотр профиля
Код: Bash
  1. #!/bin/bash
  2.  
  3. HLP='
  4. ОПИСАНИЕ
  5.         Скрипт перемещает или копирует все файлы без директорий
  6.         из директории источника (если не указана-текущая директория)
  7.         в директорию назначения.
  8.         Одинаковые имена файлов при перемещении или копировании
  9.         в директорию назначения переименовываются добавлением
  10.         номера (до точки в расширении).
  11.  
  12. ИСПОЛЬЗОВАНИЕ
  13.         '$0' [-m|-c] -p "ШАБЛОН" -s "ДИРЕКТОРИЯ" "ДИРЕКТОРИЯ"
  14.  
  15. ПАРАМЕТРЫ
  16.         -m      Перемещать файлы
  17.         -c      Копировать файлы
  18.         -u      Перемещать или копировать только уникальные файлы
  19.                 (по md5 хешу). Вычисление хешей может занять время.
  20.  
  21.         -p "ШАБЛОН"
  22.                 Шаблон имен файлов (регистронезависимый)
  23.                 Например: "*.txt"
  24.  
  25.         -s "ДИРЕКТОРИЯ"
  26.                 Использовать указанную директорию-источник
  27.                 вместо текущей.
  28.  
  29.         "ДИРЕКТОРИЯ"
  30.                 Путь до директории в которую будут перемещатся
  31.                 или копироватся файлы.
  32. '
  33.  
  34. [ $# = 0 -o "$1" = "-h" -o "$1" = "-help" ] && { echo "$HLP"; exit; }
  35.  
  36. SRC_DIR="$PWD"
  37.  
  38. while getopts cmup:s: f
  39. do
  40.     case "$f" in
  41.         c) CMND=cp ;;
  42.         m) CMND=mv ;;
  43.         u) UNQ="y" ;;
  44.         p) PTRN="-iname \"$OPTARG\"" ;;
  45.         s) SRC_DIR="$OPTARG" ;;
  46.     esac
  47. done
  48.  
  49. [ "$CMND" ] || { echo "Ошибка: Не выбрано действие: копирование или перемещение." >&2; exit; }
  50.  
  51. [ -d "$SRC_DIR" ] || { echo "Ошибка: Директория источник: \"$SRC_DIR\" не найдена." >&2; exit; }
  52.  
  53. DEST_DIR="${!#}"
  54. [ -d "$DEST_DIR" ] || { echo "Ошибка: Директория назначения: \"$DEST_DIR\" не найдена." >&2; exit; }
  55.  
  56. if [ "$UNQ" ]; then
  57.         echo "Вычисление хешей файлов..." >&2
  58.         FILES="$(eval find \"$SRC_DIR\" -type f "$PTRN" -exec md5sum {} + | sort -k1 | uniq -w 32 | cut -d ' ' -f3-)"
  59. else
  60.         FILES="$(eval find \"$SRC_DIR\" -type f "$PTRN")"
  61. fi
  62.  
  63. [ $CMND = "cp" ] && echo "Копирование файлов..."  >&2 || echo "Перемещение файлов..." >&2
  64.  
  65. IFS=$'\n'
  66. for FILE in $FILES
  67. do
  68.         FILE_NAME="${FILE##*/}"
  69.         FILE_DIR="${FILE%/*}"
  70.  
  71.         BASE="${FILE_NAME%.*}"
  72.         [ "$BASE" ] || BASE="$FILE_NAME"
  73.  
  74.         [[ "$FILE_NAME" = *.* ]] && EXT=".${FILE_NAME##*.}" || EXT=
  75.  
  76.         DEST_FILE="${BASE}${EXT}"
  77.         ADDED=n
  78.         N=2
  79.         while [ -f "$DEST_DIR/$DEST_FILE" ]
  80.         do
  81.                 DEST_FILE="${BASE}_${N}${EXT}"
  82.                 ((N+=1))
  83.                 ADDED=y
  84.         done
  85.         [ $ADDED = y ] && echo "\"$FILE_NAME\" > \"$DEST_FILE\" DIR: \"$FILE_DIR\""
  86.         $CMND "$FILE" "$DEST_DIR/$DEST_FILE"
  87. done
  88. echo "Завершено." >&2
  89.  
  90.  

1. Cкрипт можно назвать например Mv_cp_to_dir.sh, положить в ~/bin, и добавить права на исполнение.
2. Из любой директории файлы из которой хотите переместить или скопировать куда-то:
указываем параметры и путь куда переместить или скопировать файлы, например:
Mv_cp_to_dir.sh -m "/path/to/dest/dir"Ентер, готово.

Чтобы убрать пробельные отступы добавляемые движком сайта при копировании кода:
sed -i 's/^    //' Mv_cp_to_dir.sh
« Последнее редактирование: 16 Август 2016, 18:13:42 от renzrv »

adawdp

  • Автор темы
  • Гость
2016 Aug 15; 11:14 PM; Oakville, ON, Canada.

— Спасибо, renzrv, я не знаю почему общественность слабо реагирует, ведь довольно часто,к примеру, приходится собирать фотографии из разных директорий, а фотографии часто фотоаппаратом называются одинаково.
— Я встречал различные частные «однострочники» сбора изображений. Но проблема ведь именно часто в дубликатах, естественно какие-то операции с дубликатами не помешают, если есть время, то сделайте, то о чём Вы написали, я точно оценю :), а заодно может и общественность проснётся :)!

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 1967
    • Просмотр профиля
Добавил "только уникальные файлы" -опция -u,
добавил сообщения о переименовании имен файлов.
Сообщения о переименовании если их ожидается много можно направить в лог:
Mv_cp_to_dir.sh -c -u "/path/to/dest/dir" > log.txtостальные сообщения скрипта при этом в лог не попадут.
« Последнее редактирование: 16 Август 2016, 18:17:17 от renzrv »

adawdp

  • Автор темы
  • Гость
2016 Aug 17; 07:44 AM; Oakville, ON, Canada.

— Я думаю, renzrv, что вопрос исчерпан, можно даже сказать ниже дна :), исходя из поставленной задачи, естественно!
— Ещё раз спасибо, буду рекомендовать к использованию!

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 1967
    • Просмотр профиля
adawdp, Вот более быстый и простой вариант без скриптов, баш циклов, проверок, и т.д
Минус только в том, что ко всем именам файлов в конечной директории добавляется номер:
DEST_DIR=''; \
find "$PWD" -type f \
| sed -rn 's|^(.*/)([^/]+)$|\2/\1\2|p' \
| sort -t/ -k1 | cut -d/ -f2- | nl \
| sed -rn "s|^\s*([0-9]+)\s*(.+/)([^/]+)$|\2\3\n$DEST_DIR/\1 \3|p" \
| xargs -d '\n' -L2 -n2 cp
В find'е после (-type f) можно добавить шаблон имени (-name "" или -iname "")
cp в конце (копирование) можно заменить на mv (перемещение)
Конечная директория DEST_DIR желательно должна быть пустой.

Вариант "только уникальные файлы":
DEST_DIR=''; \
find "$PWD" -type f -exec md5sum {} + \
| sort -k1 | uniq -w 32 | cut -d ' ' -f3- \
| sed -rn 's|^(.*/)([^/]+)$|\2/\1\2|p' \
| sort -t/ -k1 | cut -d/ -f2- | nl \
| sed -rn "s|^\s*([0-9]+)\s*(.+/)([^/]+)$|\2\3\n$DEST_DIR/\1 \3|p" \
| xargs -d '\n' -L2 -n2 cp
« Последнее редактирование: 29 Октябрь 2016, 16:33:18 от renzrv »

 

Страница сгенерирована за 0.117 секунд. Запросов: 24.