15

Is it possible to automatically rename a file when it's placed in a specific directory?

For example I have a directory named "dir0".I move or copy a file named "file1" to "dir0".then "file1" should rename to "file1_{current timestamp}"

Nick.h
  • 6,323

3 Answers3

21

Usually you would do this programatically at the time you create or move the file, but it is possible to trigger a script whenever a file gets created or moved to a folder using incron. Set up your tab file using incrontab -e with a line like this, but with your paths of course:

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

Then in /path/to/script write a quick rename action. Be aware that the script will also get called for the new file that you create, so it has to test whether the file has been appropriately named already or not. In this example it checks to see if the file has a ten-digit number for seconds from epoch as the last part of the file name, and if it doesn't, it adds it:

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

Edit: When I first wrote this up I was short on time and couldn't figure out how to make bash do the pattern matching here. Gilles pointed out how to do this without invoking grep using ERE matching in bash:

#!/bin/bash
[[ ! ( $1 =~ _[0-9]{10}$ ) ]] && mv "$1" "$1_$(date +%s)"
jasonwryan
  • 73,126
Caleb
  • 70,105
5

I think that inotify is tool that coul be used in this case. In Debian there is tool inoticoming for executing action on file creation:

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

{} will be replaced with the filename.

The command that I provided isn't complete - it cause a loop because when the file will be renamed it will be recognized as new so it will get mved AGAIN and so on. To avoid this you could use --suffix option if you know what suffix will be in file before rename.

Caleb
  • 70,105
pbm
  • 25,387
  • No problem. I've never heard of inoticoming. Out of curiosity, when would it be better to use this over inocron? – Caleb Jul 04 '11 at 15:31
  • I don't know if it is better. I heard about it some time ago, but I never tried it... Now I found opinion that inoticoming is "similar to incrond, but lighter weight and not started as a default daemon", so I think it's just another solution with slighly different approach... I think that incron is more popular - I have little trouble to find inoticoming home page an package for it outside Debian... – pbm Jul 04 '11 at 15:45
  • I think you just posted the wrong link. My distro doesn't seem to have it anywhere. – Caleb Jul 04 '11 at 15:51
  • I found inoticoming only in Debian based distributions (in my Gentoo there is no ebuild for it). On page that I posted there are two packages: reprepro and below it inoticoming... – pbm Jul 04 '11 at 15:57
2

You could just take a script like this and have it running... I'll leave it as an exercise for the reader to add the extra bits to have it start as a service and prevent multiple copies running at once.

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

And here's it working:

$ 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
  • Of course perl can do anything, but a persistent script that runs on a X-second while-true loop is definitely a hack when you can get event notifications about file-writes and respond instantly without wasting resources the rest of the time. – Caleb Jul 04 '11 at 15:04
  • @Caleb - Very true. Just giving possibilities. Of course, if you're doing it via system notification, you have the possibility of getting two file creates with the same name within the same second, so the attached scripts should handle those circumstances. – unpythonic Jul 04 '11 at 19:22