Назад | Перейти на главную страницу

Перемещение файлов из одной папки в другую в зависимости от определенных условий

У меня сотни тысяч папок с фотографиями. По какой-то причине при экспорте они создали несколько сценариев вроде этого:

2019/01/01
2019/01/01 #2

Как мне написать команду linux (в идеале, которую можно запустить на Mac), которая может автоматически перемещать файлы

from 
2019/01/01 #2 
to 
2019/01/01

Любая помощь будет оценена. Это должно работать на любую дату, а также объединить содержимое. Я не могу понять, как получить каталог в качестве исходного формата без #

for dir in *#2/*; do mv "$dir"/* "${dir}"; done

Сделайте резервную копию ваших файлов, прежде чем попробовать это. Это могло быть разрушительно ...

Часть проблемы заключается в использовании for при переборе папок с пробелами в именах. Вы получите непоследовательный список, потому что пробел и возврат каретки являются разделителями полей. Вам нужно установить IFS только на возврат каретки. (Ты можешь использовать find -exec работать с записями файловой системы напрямую, но это становится грязным при работе с вложенными подстановочными знаками)

Это должно сработать, но имейте в виду, что перемещенные файлы заменят совпадающие файлы в папках назначения. Запустите его из корневой папки выше.

# Set IFS to carriage return only.
IFS='
'
# Find all the matching folders and move the .jpg files out of them to the sibling folder.
for a in $(find . -type d -name *#*); do b=${a::-3}; mv $a/*.jpg $b/; rmdir $a; done

Сделано несколько предположений: - что описанная вами структура представляет собой подпапки года / месяца / дня. (Если имена папок содержат \ становится все уродливее) - что у вас просто есть папки с #2 суффикс - что вы хотите удалить папки №2 после перемещения файлов.

Видеть Вот о том, как делать более странные вещи со строками в bash ...

С помощью find и -exec:

find . -type d -name "* #*" -exec bash -O nullglob -c '
  for dir; do
    otherdir=${dir/ #*}
    if [ -d "$otherdir" ]; then
      for file in "$dir"/*; do
        mv -vi "$file" "$otherdir"
      done
      rmdir "$dir" && echo "deleted directory $dir"
    else
      mv -v "$dir" "$otherdir"
    fi
  done
' bash {} +

Это переместит все файлы, например, из 2019/01/01 #2 к 2019/01/01 если последний каталог существует (если он не существует, папка с # переименован). Если есть файлы в 2019/01/01 #2 который уже существует в другой папке, он запрашивает разрешение на перемещение файлов.
Когда операция перемещения завершена, он пытается удалить (теперь пустую) папку. Все операции перемещения / удаления выполняются в подробном режиме.

Включенный nullglob в сочетании с циклом for гарантирует, что "$dir"/* не возвращает файлы, если каталог уже пуст.