Переместить файлы, которые не используются, и сохранить структуру каталогов - PullRequest
0 голосов
/ 05 марта 2019

Я пытаюсь переместить файлы из исходной папки, в которую постоянно выполняется запись (Файлы и папки).Как только файл больше не записывается, он больше не будет перезаписываться.Я хочу переместить файлы, которые не используются, в другую папку, но с сохранением структуры каталогов.В конце концов я захочу добавить это в непрерывный цикл или запустить его через равные промежутки времени, чтобы «очистить» исходную папку.

Вот мой пример до и после:

Before:
Parent/
├── Source/
│   ├── DirA/
│   │   ├── File1InUse.abc
│   │   ├── File2NotInUse.abc
│   │   └── File3InUse.abc
│   └── DirB/
│       ├── File4InUse.abc
│       ├── File5NotInUse.abc
│       └── File6NotInUse.abc
│
├── Destination/

After:
Parent/
├── Source/
│   ├── DirA/
│   │   ├── File1InUse.abc
│   │   └── File3InUse.abc
│   └── DirB/
│       └── File4InUse.abc
│
├── Destination/
    ├── DirA/   
    │   └── File2NotInUse.abc
    └── DirB/
        ├── File5NotInUse.abc
        └── File6NotInUse.abc

Я нашел ответов на перемещение файлов, которые перемещают файлы, которые не используются:

comm -2 -3 <(find $dir -maxdepth 1 -type f|sort) <(sudo lsof $dir/* | awk '(NR>1) {print $9}'|sort) | xargs -I {} mv {} $move_dir

Я также нашел ответы на перемещение файлов и сохранение структуры каталогов:

возможно с rsync:

rsync -axuv --delete-after --progress Source/ Target/

Я не такойзнающий в командной строке, поэтому я не уверен, как соединить эти два понятия.

Спасибо за любую помощь.

1 Ответ

0 голосов
/ 05 марта 2019

Вот как я это сделаю.Сценарий создан для того, чтобы вы могли использовать его из других программ или заданий cron.

#! /bin/bash

isUsed() {
    test -w "$1" && echo 1 || echo 0
}

parent_dir=$1
src_dir=$2
dst_dir=$3

while read -r line
do
    retval=$(isUsed "$line")
    if [ $retval -eq "0" ]
    then
        filepath=$(dirname $line)
        filepath=${filepath#$parent_dir}
        filepath=${filepath#$src_dir}
        mkdir -p "$parent_dir$dst_dir$filepath"
        mv "$line" "$parent_dir$dst_dir$filepath"/
    fi
done <<< $(find "$parent_dir$src_dir")

Использование

./script.sh Parent/ Source/ Destination/

Работа

  1. isUsed Функция используется для проверки, используется ли файл в настоящее время или нет.

    Возвращаемое значение: 1 - файл используется, 0- файл не используется

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

  2. find "$parent_dir$src_dir" выведет список всех файлов и каталогов вданный путь.Вывод команды find считывается по одному в $line с использованием цикла while.

    Пример: Предположим, что $line равно Parent/Source/DirA/File2NotInUse.abc

  3. Мы вызываем функцию isUsed, чтобы проверить, используется ли файл или нет.Возвращаемое значение вызова функции сохраняется в $retval

  4. Если $retval равно "0", это означает, что файл не используется, и мы должны переместить его в место назначенияdirectory.

  5. Сначала мы сгенерируем путь к файлу, который нужно переместить, используя dirname.Он вернет относительный путь к файлу.

    $filepath равно Parent/Source/DirA

    Затем мы удаляем имя родительского каталога из filepath.

    Поэтому $filepath становится Source/DirA

    Затем мы удаляем имя исходного каталога из filepath.

    Следовательно, $filepath теперь равно DirA.В результате filepath будет путем к файлу относительно исходного каталога.

  6. Создайте каталог в Destination/ с указанным filepath.mkdir -p создаст все промежуточные каталоги, как указано в filepath.

    mkdir -p Parent/Destination/DirA

  7. Последний шаг - переместить текущий файл из Source.путь к вновь созданному пути Destination.

    mv Parent/Source/DirA/File2NotInUse.abc Parent/Destination/DirA/

...