Как в linux автоматизировать копирование файлов с переименованием?
Есть источник файлов со структурой вида yyyy\mm\Статистика за yyyymmdd.xls
Файлы в источнике добавляются каждый рабочий день. Необходимо скопировать все файлы xls содержащие слова "Статистика за", но так чтобы у целевого файла оно отсутствовало, то есть: Статистика за 20190318.xls -> 20190318.xls
Можно ли это сделать стандартными инструментами или может быть есть какие-то сторонние утилиты подходящие под эту задачу?
Сергей Быданов, всего скорее так, потому что я тестировал на файле расположенном в том же каталоге, где и выполнялся скрипт (т.е. без подпапок).
Я думаю, ты уже разобрался, но напишу чуть подробнее, для тех кто придет сюда позже:
find -name "*.xls" -exec sh -c 'mv "$1" `echo $1 | grep -o -E "[0-9]+"`.xls' sh {} \;
вот эта часть ищет файлы с расширением xls и выполняет для каждого найденого резульатата дальнейшую команду find -name "*.xls" -exec sh -c
т.е. если понадобиться усложнить маску поиска файлов, то править надо именно тут, например выбрать файлы только с вхождением "за 2018"..
Далее команда которая будет применена к каждому найденому файлу mv "$1" `echo $1 | grep -o -E "[0-9]+"`.xls
mv = стандартная команда перемещения файла, формат mv <откуда> <куда>
откуда: $1 = путь найденный командой find (т.е. полное имя файла "Статистика за 20190318.xls")
куда: выражение echo $1 | grep -o -E "[0-9]+"`.xls
echo $1 | grep -o -E "[0-9]+"`.xls
echo $1 = вывести имя файла ("./Статистика за 20190318.xls"), которое через pipeline передается в следующую команду
grep -o -E "[0-9]+" = оставляет только цифры из строки ("./Статистика за 20190318.xls" => "20190318")
.xls = вконце добавляется .xls, т.к. оно будет потерто grep-ом
Именно в этом месте, из "Статистика за 20190318.xls" удаляется все кроме цифр и приклеивается .xls, в итоге имеем "20190318.xls"
Чтобы поменять логику, например имя файла будет "Статистика за 2019-03-18.xls" и на выходе надо "2019-03-18.xls", надо менять обработку именно тут. Обработать можно множеством способов, погуглить можно так "Обработка строк в bash"
Все это выражение заключено в кавычки, те что на букве Ё. Я их называю "обратные кавычки", но правильно грависы или backticks. Такая конструкция выполняет то, что указано внутри и возвращает результат. Тоже самое можно сделать, используя конструкцию $(...). Т.е. просто берем $1 (полное имя файла), обрабатываем его и возвращаем новое.
Теперь, вся магия раскрыта и можно составить пару выражений, для тестирования
Поиск файлов и просмотр что передается в $1 find -name "*.xls" -exec sh -c 'echo $1' sh {} \;
Результат (один в один файловая структура)
./123/20190318.xls
./20190318.xls
Тестирование обработки (того, что получится в итоге)
find -name "*.xls" -exec sh -c 'echo `echo $1 | grep -o -E "[0-9]+"`.xls' sh {} \;
Результат
123 20190318.xls
20190318.xls
Обратите внимание, что произошло с путем имеющим вложенный файл - исчезли точки и слеши, чтобы исправить можно поменять регулярку, чтобы она оставляла слеши и точки
find -name "*.xls" -exec sh -c 'echo `echo $1 | grep -o -E "[0-9./]+"`xls' sh {} \;
Результат:
./123/20190318.xls
./20190318.xls
В общем, в зависимости от задачи (есть те или иные символы в именах), надо менять регулярку или весь процесс обработки имени файла.