Ganti nama file secara otomatis ketika ditempatkan di direktori tertentu

14

Apakah mungkin untuk secara otomatis mengganti nama file ketika ditempatkan di direktori tertentu?

Misalnya saya memiliki direktori bernama "dir0". Saya memindahkan atau menyalin file bernama "file1" ke "dir0". Maka "file1" harus berganti nama menjadi "file1_ {timestamp saat ini}"

Nick.h
sumber
1
Lihatlah inotify ( linux.die.net/man/7/inotify ). Tetapi tidak bisakah Anda langsung menyalin ke file yang dinamai dengan benar dengan stempel waktu yang ditambahkan?
alex

Jawaban:

21

Biasanya Anda akan melakukan ini secara terprogram pada saat Anda membuat atau memindahkan file, tetapi dimungkinkan untuk memicu skrip setiap kali file dibuat atau dipindahkan ke folder menggunakan incron. Siapkan file tab Anda menggunakan incrontab -edengan garis seperti ini, tetapi dengan jalur Anda tentu saja:

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

Kemudian dalam /path/to/scriptmenulis tindakan ganti nama cepat. Ketahuilah bahwa skrip juga akan dipanggil untuk file baru yang Anda buat, sehingga harus menguji apakah file tersebut telah dinamai dengan tepat atau tidak. Dalam contoh ini memeriksa untuk melihat apakah file memiliki angka sepuluh digit untuk detik dari zaman sebagai bagian terakhir dari nama file, dan jika tidak, ia menambahkannya:

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

Sunting: Ketika saya pertama kali menulis ini saya kekurangan waktu dan tidak tahu bagaimana membuat bashpola yang cocok di sini. Gilles menunjukkan cara melakukan ini tanpa menggunakan grep menggunakan pencocokan ERE di bash:

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

Saya pikir itu inotifyadalah alat yang dapat digunakan dalam kasus ini. Di Debian ada alat inoticominguntuk mengeksekusi tindakan pada pembuatan file:

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

{} akan diganti dengan nama file.

Perintah yang saya berikan tidak lengkap - itu menyebabkan perulangan karena ketika file akan diganti namanya akan dikenali sebagai baru sehingga akan mvdiedit LAGI dan seterusnya. Untuk menghindari ini, Anda bisa menggunakan --suffixopsi jika Anda tahu sufiks apa yang akan ada dalam file sebelum mengganti nama.

pbm
sumber
Tidak masalah. Saya belum pernah mendengarnya inoticoming. Karena penasaran, kapan lebih baik menggunakan ini inocron?
Caleb
Saya tidak tahu apakah itu lebih baik. Saya mendengarnya beberapa waktu lalu, tetapi saya tidak pernah mencobanya ... Sekarang saya menemukan pendapat yang inoticoming"mirip dengan incrond, tetapi bobotnya lebih ringan dan tidak dimulai sebagai daemon default", jadi saya pikir itu hanyalah solusi lain dengan pendekatan yang sedikit berbeda. .. Saya pikir itu incronlebih populer - Saya punya sedikit kesulitan untuk menemukan inoticoming halaman rumah paket untuk itu di luar Debian ...
pbm
Saya pikir Anda baru saja memposting tautan yang salah. Distro saya sepertinya tidak memilikinya di mana pun.
Caleb
Saya inoticominghanya menemukan di distribusi berbasis Debian (di Gentoo saya tidak ada ebuild untuk itu). Pada halaman yang saya posting ada dua paket: repreprodan di bawahnya inoticoming...
pbm
2

Anda bisa saja mengambil skrip seperti ini dan menjalankannya ... Saya akan membiarkannya sebagai latihan bagi pembaca untuk menambahkan bit ekstra agar dimulai sebagai layanan dan mencegah beberapa salinan berjalan sekaligus.

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

Dan ini dia berfungsi:

$ 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
sumber
Tentu saja perl bisa melakukan apa saja, tetapi skrip persisten yang berjalan pada perulangan X-detik sementara-benar jelas merupakan peretasan ketika Anda bisa mendapatkan pemberitahuan acara tentang penulisan file dan merespons secara instan tanpa menghabiskan sumber daya sepanjang waktu.
Caleb
@ Caleb - Sangat benar. Hanya memberi kemungkinan. Tentu saja, jika Anda melakukannya melalui pemberitahuan sistem, Anda memiliki kemungkinan mendapatkan dua file yang dibuat dengan nama yang sama dalam detik yang sama, sehingga skrip yang dilampirkan harus menangani keadaan tersebut.
unpythonic