Renommer automatiquement les fichiers lorsqu'ils sont placés dans un répertoire spécifique


14

Est-il possible de renommer automatiquement un fichier lorsqu'il est placé dans un répertoire spécifique?

Par exemple, j'ai un répertoire nommé "dir0" .Je déplace ou copie un fichier nommé "file1" dans "dir0".


1
Jetez un œil à inotify ( linux.die.net/man/7/inotify ). Mais ne pouvez-vous pas tout de suite copier dans le fichier correctement nommé avec un horodatage supplémentaire?
alex

Réponses:


21

Habituellement, vous le feriez par programmation au moment où vous créez ou déplacez le fichier, mais il est possible de déclencher un script chaque fois qu'un fichier est créé ou déplacé vers un dossier à l'aide incron. Configurez votre fichier tab en utilisant incrontab -eune ligne comme celle-ci, mais avec vos chemins bien sûr:

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

Puis en /path/to/scriptécrivant une action de renommage rapide. Sachez que le script sera également appelé pour le nouveau fichier que vous créez, il doit donc tester si le fichier a déjà été correctement nommé ou non. Dans cet exemple, il vérifie si le fichier a un nombre à dix chiffres pendant secondes de epoch comme dernière partie du nom de fichier, et si ce n'est pas le cas, il l'ajoute:

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

Edit: Quand j'ai écrit ceci pour la première fois, je manquais de temps et je ne pouvais pas comprendre comment faire bashla correspondance des motifs ici. Gilles a expliqué comment faire cela sans invoquer grep en utilisant la correspondance ERE dans bash:

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

5

Je pense que inotifyc'est l'outil qui pourrait être utilisé dans ce cas. Dans Debian, il existe un outil inoticomingpour exécuter une action sur la création de fichiers:

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

{} sera remplacé par le nom de fichier.

La commande que j'ai fournie n'est pas complète - elle provoque une boucle car lorsque le fichier sera renommé, il sera reconnu comme nouveau, il sera donc à nouveau mvédité, etc. Pour éviter cela, vous pouvez utiliser l' --suffixoption si vous savez quel suffixe sera dans le fichier avant de le renommer.


Aucun problème. Je n'en ai jamais entendu parler inoticoming. Par curiosité, quand serait-il préférable de l'utiliser à nouveau inocron?
Caleb

Je ne sais pas si c'est mieux. J'en ai entendu parler il y a quelque temps, mais je ne l'ai jamais essayé ... Maintenant, j'ai trouvé une opinion qui inoticomingest "similaire incrond, mais plus légère et qui n'a pas commencé comme démon par défaut", donc je pense que c'est juste une autre solution avec une approche légèrement différente. .. Je pense que incronc'est plus populaire - j'ai peu de mal à trouver un paquet pour la inoticoming page d'accueil en dehors de Debian ...
pbm

Je pense que vous venez de publier le mauvais lien. Ma distribution ne semble l'avoir nulle part.
Caleb

Je n'ai trouvé inoticomingque dans les distributions basées sur Debian (dans mon Gentoo il n'y a pas d'ebuild pour ça). Sur la page que j'ai publiée, il y a deux packages: repreproet en dessous inoticoming...
pbm

2

Vous pouvez simplement prendre un script comme celui-ci et le faire tourner ... Je vais laisser au lecteur un exercice pour ajouter les bits supplémentaires afin qu'il démarre en tant que service et empêcher l'exécution de plusieurs copies à la fois.

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

Et ça marche:

$ 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

Bien sûr, tout perl peut être fait, mais un script persistant qui s'exécute sur une boucle X-seconde while-true est définitivement un hack lorsque vous pouvez recevoir des notifications d'événements sur les écritures de fichiers et répondre instantanément sans gaspiller les ressources le reste du temps.
Caleb

@Caleb - Très vrai. Donner juste des possibilités. Bien sûr, si vous le faites via une notification système, vous avez la possibilité d'obtenir deux fichiers créés avec le même nom dans la même seconde, les scripts joints doivent donc gérer ces circonstances.
unpythonic
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.