Автоматически переименовывать файлы, когда они помещены в определенный каталог

14

Можно ли автоматически переименовать файл, когда он помещен в определенный каталог?

Например, у меня есть каталог с именем «dir0». Я перемещаю или копирую файл с именем «file1» в «dir0». Затем «file1» следует переименовать в «file1_ {current timestamp}»

Nick.h
источник
1
Посмотрите на inotify ( linux.die.net/man/7/inotify ). Но вы не можете просто скопировать в файл с правильно названным именем с добавленной отметкой времени?
Alex

Ответы:

21

Обычно вы делаете это программно во время создания или перемещения файла, но можно запускать сценарий всякий раз, когда файл создается или перемещается в папку с помощью incron. Настройте свой файл вкладок, используя incrontab -eследующую строку, но, конечно, с вашими путями:

/path/to/dir0 IN_MOVED_TO,IN_CREATE /path/to/script $@/$#

Затем /path/to/scriptнапишите быстрое действие переименования. Имейте в виду, что сценарий также будет вызываться для нового файла, который вы создаете, поэтому он должен проверить, было ли имя файла соответствующим образом уже названо или нет. В этом примере он проверяет, имеет ли файл десятизначное число секунд с начала эпохи в качестве последней части имени файла, и если нет, добавляет его:

#!/bin/bash
echo $1 | grep -qx '.*_[0-9]\{10\}' || mv "$1" "$1_$(date +%s)"

Изменить: Когда я впервые написал это, у меня было мало времени, и я не мог понять, как заставить bashсделать сопоставление с образцом здесь. Жиль указал, как это сделать, не вызывая grep, используя ERE match в bash:

#!/bin/bash
[[ ! ( $1 =~ _[0-9]{10}$ ) ]] && mv "$1" "$1_$(date +%s)"
Калеб
источник
5

Я думаю, что inotifyэто инструмент, который может быть использован в этом случае. В Debian есть инструмент inoticomingдля выполнения действий по созданию файла:

 inoticoming --foreground /path/to/directory mv {} {}-"`date`" \;

{} будет заменено на имя файла.

Команда, которую я предоставил, не завершена - она ​​вызывает цикл, потому что, когда файл будет переименован, он будет распознан как новый, поэтому он получит mvEd AGAIN и так далее. Чтобы избежать этого, вы можете использовать --suffixопцию, если вы знаете, какой суффикс будет в файле перед переименованием.

постоянный репер
источник
Нет проблем. Я никогда не слышал о inoticoming. Из любопытства, когда было бы лучше использовать это снова inocron?
Калеб
Я не знаю, лучше ли это. Я слышал об этом некоторое время назад, но никогда не пробовал ... Теперь я нашел мнение, inoticomingкоторое "похоже на incrond, но имеет меньший вес и не запускается как демон по умолчанию", поэтому я думаю, что это просто еще одно решение с немного другим подходом. .. Я думаю, что incronэто более популярно - у меня нет проблем с поиском inoticoming домашней страницы пакета для него вне Debian ...
pbm
Я думаю, что вы только что разместили неправильную ссылку. У моего дистрибутива, похоже, его нет нигде.
Калеб
Я нашел inoticomingтолько в дистрибутивах на основе Debian (в моем Gentoo нет ebuild для него). На странице, которую я разместил, есть два пакета: repreproи под ним inoticoming...
pbm
2

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

#!/usr/bin/perl
use strict;
use warnings;
use File::Slurp;
use POSIX qw(strftime);

chdir($ENV{STAMP_DIR} || '/home/me/dir0')
    or die "Cannot get to stamp dir: $!\n";

while (1) {
    my $stamp = strftime("_%Y%m%d%H%M%S", localtime);
    for my $orig ( grep { $_ !~ /_\d{14}$/ } read_dir('.') ) {
        rename $orig, "$orig$stamp"
            or warn "Failed to rename $orig to $orig$stamp: $!\n";
    }
    sleep($ENV{STAMP_DELAY} || 10);
}

И вот оно работает:

$ STAMP_DIR=/home/me/stamps STAMP_DELAY=1 ./t.pl &
[1] 6989
$ cd stamps/
$ ls
$ touch hello
$ ls
hello_20110704033253
$ touch world
$ ls
hello_20110704033253
world_20110704033258
$ touch hello
$ ls
hello_20110704033253
hello_20110704033302
world_20110704033258
unpythonic
источник
Конечно, perl можно делать все что угодно, но постоянный сценарий, который запускается по циклу X-секунда while-true, определенно является хаком, когда вы можете получать уведомления о событиях о записи файлов и мгновенно отвечать, не тратя ресурсы остальное время.
Калеб
@ Калеб - Очень верно. Просто даю возможности. Конечно, если вы делаете это через системное уведомление, у вас есть возможность получить два файла с одинаковыми именами за одну секунду, поэтому прилагаемые сценарии должны справиться с этими обстоятельствами.
unpythonic