Como posso adicionar em massa a data de criação de um arquivo ao nome do arquivo?

2

Eu gerou uma série de imagens com lapso de tempo e as nomeei sequencialmente {0000..9999}.jpg

Isso não é ótimo para navegar em todo o conjunto, pois é mais difícil dizer quando determinada imagem foi tirada do nome do arquivo. Eu gostaria de renomeá-los para que seus nomes contenham sua data de criação, por exemplo:

0000.jpg → 20140815-142800-0000.jpg
0001.jpg → 20140815-142800-0001.jpg
0002.jpg → 20140815-142800-0002.jpg

É importante preservar os elementos do nome do arquivo original e a formatação exata da data não é importante , desde que seja segura e fácil de entender pelo nome do arquivo. Meu exemplo acima insere-o na frente de uma forma que é propício para a classificação por data.

Se você quiser testar os arquivos, o seguinte criará 10 arquivos com tempos de criação crescentes:

for i in {00..02}; do touch --date "2014-08-15 $i:$i:$i" 00$i.jpg; done
    
por Oli 15.08.2014 / 17:10

3 respostas

1

Você pode usar rename com uma expressão Perl real

$ rename 's/(\d+\.jpg)/use File::stat; sprintf("%s-%s", stat($&)->mtime, )/e' * -v
0000.jpg renamed as 1408057200-0000.jpg
0001.jpg renamed as 1408060861-0001.jpg
0002.jpg renamed as 1408064522-0002.jpg

Isso deixa os arquivos com um tempo desde a época. Encontrar por classificação, pobre para leitura.

O único problema aqui é que você precisa combinar com o nome do arquivo inteiro (para que você possa declarar $& - todo o jogo - dentro da substituição). Isso pode ficar um pouco cansativo com nomes realmente complicados.

Podemos construir sobre isso para ter uma formatação de data mais convencional:

$ rename 's/(\d+\.jpg)/use File::stat; use POSIX; sprintf("%s-%s", strftime("%Y%m%d-%H%M%S", localtime(stat($&)->mtime)), )/e' * -vn
0000.jpg renamed as 20140815-000000-0000.jpg
0001.jpg renamed as 20140815-010101-0001.jpg
0002.jpg renamed as 20140815-020202-0002.jpg
    
por Oli 15.08.2014 / 17:10
1

E algo baseado em bash para nomes de arquivos simples (como o exemplo):

$ for f in *; do mv "$f" "$(date -d@$(stat --printf='%Y' "$f") +%Y%m%d%H%M%S)-$f"; done
$ ls -l
total 0
-rw-rw-r-- 1 oli oli 0 Aug 15 00:00 20140815000000-0000.jpg
-rw-rw-r-- 1 oli oli 0 Aug 15 01:01 20140815010101-0001.jpg
-rw-rw-r-- 1 oli oli 0 Aug 15 02:02 20140815020202-0002.jpg
    
por Oli 15.08.2014 / 17:16
1

Aqui está algo que eu retrabalhei para que eu pudesse realmente entender o que estava acontecendo. Obrigado.

for file in *.log; 
    do
        created=$(stat -f "%m" $file)
        dateHat=$(date -r $created "+%F" )
        sizeBytes=$(stat -f "%z" $file)
        mv $file $dateHat"_size_"$sizeBytes"_"$file
    done
    
por Jonathan Carter Hebert 14.07.2017 / 21:05