Renomear arquivos automaticamente quando eles são colocados em um diretório específico


14

É possível renomear automaticamente um arquivo quando ele é colocado em um diretório específico?

Por exemplo, eu tenho um diretório chamado "dir0". Movo ou copio um arquivo chamado "file1" para "dir0". Então "file1" deve renomear para "file1_ {current timestamp}"


1
Dê uma olhada no inotify ( linux.die.net/man/7/inotify ). Mas você não pode simplesmente copiar para o arquivo nomeado corretamente com o carimbo de data / hora adicionado imediatamente?
— alex

Respostas:


21

Normalmente, você faria isso programaticamente no momento em que cria ou move o arquivo, mas é possível disparar um script sempre que um arquivo é criado ou movido para uma pasta usando incron. Configure seu arquivo de tabulação usando incrontab -euma linha como esta, mas com seus caminhos, é claro:

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

Em seguida, /path/to/scriptescreva uma ação de renomeação rápida. Esteja ciente de que o script também será chamado para o novo arquivo que você cria, portanto, ele deve testar se o arquivo já foi nomeado adequadamente ou não. Neste exemplo, ele verifica se o arquivo tem um número de dez dígitos por segundos a partir da época como a última parte do nome do arquivo e, se não tiver, adiciona-o:

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

Edit: Quando eu escrevi isso, eu estava com pouco tempo e não conseguia descobrir como bashfazer o padrão correspondente aqui. Gilles apontou como fazer isso sem chamar o grep usando a correspondência ERE no bash:

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

5

Eu acho que inotifyé uma ferramenta que pode ser usada neste caso. No Debian, existe uma ferramenta inoticomingpara executar ações na criação de arquivos:

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

{} será substituído pelo nome do arquivo.

O comando que eu forneci não está completo - causa um loop, porque quando o arquivo for renomeado, ele será reconhecido como novo e será mveditado novamente. Para evitar isso, você pode usar a --suffixopção se você souber qual sufixo estará no arquivo antes de renomear.


Sem problemas. Eu nunca ouvi falar disso inoticoming. Por curiosidade, quando seria melhor usar isso de novo inocron?
— Caleb

Não sei se é melhor. Ouvi falar disso há algum tempo, mas nunca tentei ... Agora achei uma opinião inoticoming"semelhante a incrond, mas mais leve e não iniciada como um daemon padrão", então acho que é apenas mais uma solução com uma abordagem ligeiramente diferente. .. Eu acho que isso incroné mais popular - tenho poucos problemas para encontrar um pacote para a inoticoming home page fora do Debian ... #
— 234

Acho que você acabou de postar o link errado. Minha distribuição não parece ter isso em lugar nenhum.
— Caleb

Eu encontrei inoticomingapenas em distribuições baseadas no Debian (no meu Gentoo não há ebuild para isso). Na página que eu publiquei, existem dois pacotes: repreproe abaixo dela inoticoming... #
— 234

2

Você pode pegar um script como esse e colocá-lo em execução ... Vou deixar como um exercício para o leitor adicionar os bits extras para que ele comece como um serviço e impedir que várias cópias sejam executadas ao mesmo tempo.

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

E aqui está o trabalho:

$ 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

É claro que perl pode fazer qualquer coisa, mas um script persistente que é executado em um loop while-true de X segundos é definitivamente um hack quando você pode receber notificações de eventos sobre gravação de arquivos e responder instantaneamente sem desperdiçar recursos o resto do tempo.
— Caleb

@ Caleb - Muito verdade. Apenas dando possibilidades. Obviamente, se você estiver fazendo isso por meio da notificação do sistema, terá a possibilidade de obter duas criações de arquivos com o mesmo nome no mesmo segundo, portanto os scripts anexados devem lidar com essas circunstâncias.
— Unpythonic
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.