Classifique imagens por data em subdirecórios

2

Eu tenho um diretório com subdiretórios que contém imagens. Quero criar um novo diretório e mover todas as imagens para lá e, em seguida, organizá-las em subdiretórios com o pedido year/month/day da modificação.

Eu pensei em usar find e mv para mover todas as imagens para o novo diretório, encontrar a data da primeira imagem no diretório, criar um subdiretório com o nome do ano dessa imagem e, em seguida, encontrar e mover todas as imagens com o mesmo ano nesse subdiretório. Farei isso para cada imagem no diretório principal e depois repetirei o procedimento em cada subdiretório para mês e dia.

Meu problema é que eu acredito que deve haver uma maneira mais fácil para eu fazer isso.

Alguma ideia?

    
por Chri 15.11.2017 / 14:06

1 resposta

3

com zsh :

zmodload zsh/files # bring in builtin versions of mkdir and mv to speed things up
zmodload zsh/stat

for file (**/*.jpg(N.)) {
   zstat -F %Y/%m/%d -A date +mtime -- $file &&
     mkdir -p $date &&
     mv -- $file $date
}

Se você não tiver zsh e não puder instalá-lo, com as ferramentas GNU, poderá minimizar o número de comandos executados com:

(export LC_ALL=C
  find . -name '*.jpg' -type f -printf '%TY/%Tm/%Td
zmodload zsh/files # bring in builtin versions of mkdir and mv to speed things up
zmodload zsh/stat

for file (**/*.jpg(N.)) {
   zstat -F %Y/%m/%d -A date +mtime -- $file &&
     mkdir -p $date &&
     mv -- $file $date
}
%p
(export LC_ALL=C
  find . -name '*.jpg' -type f -printf '%TY/%Tm/%Td%pre%%p%pre%' |
    gawk -v 'RS=%pre%' -v q="'" '
      function shquote(s) {
        gsub(q, q "\" q q, s)
        return q s q
      }
      {
        date = $0; getline file
        dir[date] = dir[date] " " shquote(file)
      }
      END {
        printf "mkdir -p ."
        for (d in dir) printf " %s", d
        print " || exit"
        for (d in dir) print "mv" dir[d], d
      }' | sh
)
' | gawk -v 'RS=%pre%' -v q="'" ' function shquote(s) { gsub(q, q "\" q q, s) return q s q } { date = $0; getline file dir[date] = dir[date] " " shquote(file) } END { printf "mkdir -p ." for (d in dir) printf " %s", d print " || exit" for (d in dir) print "mv" dir[d], d }' | sh )

(você pode querer remover o | sh primeiro para verificar se ele faz o que você quer).

Note que nenhum dos dois se protegerá contra conflitos. Por exemplo, se você tiver um a/foo.jpg e b/foo.jpg modificados pela última vez em 2017-11-01, ambos serão movidos para 2017/11/01/foo.jpg , um deles substituindo o outro. Você pode adicionar o -i flag a mv para protegê-lo.

    
por 15.11.2017 / 14:25

Tags