Benennen Sie Dateien automatisch um, wenn Sie in einem bestimmten Verzeichnis abgelegt werden

14

Ist es möglich, eine Datei automatisch umzubenennen, wenn sie in einem bestimmten Verzeichnis abgelegt wird?

Zum Beispiel habe ich ein Verzeichnis mit dem Namen "dir0". Ich verschiebe oder kopiere eine Datei mit dem Namen "file1" in "dir0". Dann sollte "file1" in "file1_ {current timestamp}" umbenannt werden.

Nick.h
quelle
1
Schauen Sie sich inotify an ( linux.die.net/man/7/inotify ). Aber können Sie nicht einfach sofort in die ordnungsgemäß benannte Datei mit hinzugefügtem Zeitstempel kopieren?
Alex

Antworten:

21

Normalerweise tun Sie dies programmgesteuert zum Zeitpunkt des Erstellens oder Verschiebens der Datei. Es ist jedoch möglich, ein Skript auszulösen, wenn eine Datei erstellt oder in einen Ordner verschoben wird incron. Richten Sie Ihre Tab-Datei incrontab -emit einer Zeile wie dieser ein, aber natürlich mit Ihren Pfaden:

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

Dann /path/to/scriptschreibe eine schnelle Umbenennungsaktion. Beachten Sie, dass das Skript auch für die neue Datei aufgerufen wird, die Sie erstellen. Daher muss geprüft werden, ob die Datei bereits einen geeigneten Namen hat oder nicht. In diesem Beispiel wird geprüft, ob die Datei als letzten Teil des Dateinamens eine zehnstellige Zahl für Sekunden ab der Epoche enthält. Wenn dies nicht der Fall ist, wird sie hinzugefügt:

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

Bearbeiten: Als ich das erste Mal schrieb, hatte ich zu wenig Zeit und konnte nicht herausfinden, wie bashder Pattern-Matching hier durchgeführt werden soll. Gilles wies darauf hin, wie dies ohne Aufruf von grep mit ERE-Matching in bash geschehen kann:

#!/bin/bash
[[ ! ( $1 =~ _[0-9]{10}$ ) ]] && mv "$1" "$1_$(date +%s)"
Caleb
quelle
5

Ich denke, das inotifyist ein Werkzeug, das in diesem Fall verwendet werden kann. In Debian gibt es ein Tool inoticomingzum Ausführen von Aktionen bei der Dateierstellung:

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

{} wird durch den Dateinamen ersetzt.

Der von mir angegebene Befehl ist nicht vollständig - es wird eine Schleife ausgelöst, da die Datei beim Umbenennen als neu erkannt wird mvund somit WIEDER bearbeitet wird und so weiter. Um dies zu vermeiden, können Sie die --suffixOption verwenden, wenn Sie wissen, welches Suffix vor dem Umbenennen in der Datei enthalten sein wird.

pbm
quelle
Kein Problem. Ich habe noch nie davon gehört inoticoming. Wann ist es aus Neugier besser, dies zu wiederholen inocron?
Caleb
Ich weiß nicht, ob es besser ist. Ich habe vor einiger Zeit davon gehört, aber ich habe es nie ausprobiert ... Jetzt habe ich eine Meinung gefunden, inoticomingdie "ähnlich incrond, aber leichter und nicht als Standard-Daemon gestartet" ist. Ich denke also, es ist nur eine andere Lösung mit etwas anderem Ansatz. .. ich denke , dass incronmehr populär ist - ich wenig Schwierigkeiten haben , finden inoticoming Startseite ein Paket für sie außerhalb Debian ...
pbm
Ich denke, Sie haben gerade den falschen Link gepostet. Meine Distribution scheint es nirgendwo zu haben.
Caleb
Ich habe es inoticomingnur in Debian-basierten Distributionen gefunden (in meinem Gentoo gibt es kein Ebuild dafür). Auf der Seite, die ich gepostet habe, gibt es zwei Pakete: reprepround darunter inoticoming...
PBM
2

Sie könnten einfach ein Skript wie dieses nehmen und ausführen lassen ... Ich überlasse es dem Leser als Übung, die zusätzlichen Bits hinzuzufügen, damit es als Dienst gestartet wird und nicht mehrere Kopien gleichzeitig ausgeführt werden.

#!/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);
}

Und hier ist es funktioniert:

$ 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
unpythonisch
quelle
Natürlich perl kann alles getan werden, aber ein persistentes Skript, das in einer X-Sekunden-Schleife ausgeführt wird, ist definitiv ein Hack, wenn Sie Ereignisbenachrichtigungen über das Schreiben von Dateien erhalten und sofort reagieren können, ohne den Rest der Zeit Ressourcen zu verschwenden.
Caleb
@Caleb - Sehr wahr. Ich gebe nur Möglichkeiten. Wenn Sie dies über die Systembenachrichtigung tun, haben Sie natürlich die Möglichkeit, innerhalb derselben Sekunde zwei Dateien mit demselben Namen zu erstellen, sodass die angehängten Skripte diese Umstände berücksichtigen sollten.
unpythonic