Мне нужно переместить некоторые файлы из одной папки в другую, критерии установлены find и grep. Когда я пытаюсь переместить файлы, они ломаются.
Фактический ход, который он пытается сделать, этоmv /somefolder/export//somefolder/storage/testfileOLD.txt
Я ожидал, чтоmv /somefolder/storage/testfileOLD.txt /somefolder/export/testfileOLD.txt
Команда, которую я использую:
find /somefolder/storage/ -type f -name "*OLD*" -newermt '2019-05-1' ! -newermt '2019-06-7' -exec grep -qiF 'closed' {} \; -exec mv {} /somefolder/export/{} \;
Я уже пробовал с -exec basename {}
, это дает мне правильный результат, но когда я изменяю mv на
-exec echo {} /somefolder/export/$(basename {}) \;
чтобы проверить, работает ли он, он все еще дает мне /somefolder/export//somefolder/storage/testfileOLD.txt
.
решение1
$(basename {})
потерпит неудачу (лучше: просто будет пустой строкой). Вызванная здесь подоболочка не расширяется {}
до имени файла, поскольку оно предназначено для поиска и не экспортируется в подоболочку, которую создает ваша команда.
Вы можете проверить это, запустив
find -exec echo "this will be empty:" $(basename '{}') \;
Предлагаю вам написать небольшой скрипт:
#!/bin/bash
mv "$1" /somefolder/export/"$( basename ${1})"
и запустите его в своей find
команде:
find /dir/ <specs> -exec grep -qiF 'closed' '{}' \; -exec bash script.sh '{}' \;
Насколько мне известно, поведение пересылки '{}'
в подоболочки зависит от вашей find
версии.
решение2
Если вы хотите сохранить исходную структуру ниже каталога /somefolder/somedir
, вы можете использовать rsync
вместо mv
.
Испытательная установка:
/somefolder/storage/testfileOLD.txt
/somefolder/storage/subdir/fileOLD.txt
Ожидаемый результат после хода:
/somefolder/export/testfileOLD.txt
/somefolder/export/subdir/fileOLD.txt
Команды:
# first, create a file list of relative paths (some arguments removed for simplicity)
$ find /somefolder/storage -type f -name "*OLD*" -printf '%P\n' > /tmp/filelist
# cat to illustrate its content
$ cat /tmp/filelist
subdir/fileOLD.txt
testfileOLD.txt
# then rsync using `--remove-source-files` to move the files
$ rsync -av --remove-source-files --files-from=/tmp/filelist /somefolder/storage /somefolder/export