Você pode usar exiftool
para obter informações meta de jpg, png arquivos. Para instalar o exiftool
, execute:
$ sudo apt-get install libimage-exiftool-perl
Uso: exiftool -s example.jpg
Parece que a informação mais completa é armazenada como TagsList
. Ele ainda suporta tags hierárquicas salvas pelo Shotwell, por exemplo, nature/sky
. As tags também podem ser encontradas nos campos Subject
, Keywords
, LastKeywordXMP
. Subject
, Keywords
não preserva a hierarquia de tags - você pode usá-los se não quiser criar diretórios aninhados para tags aninhadas.
Este é o script python3
que move os arquivos de imagem especificados na linha de comando para os diretórios de tag correspondentes (criando hardlinks e removendo o nome do arquivo original), por exemplo, se example.jpg
tiver a lista de tags: nature
, nature/clouds
, nature/mountain
, nature/sky
, a árvore do diretório de resultados se parece com:
.
└── nature
├── clouds
│ └── example.jpg
├── example.jpg
├── mountain
│ └── example.jpg
└── sky
└── example.jpg
Nota: sempre faça backup de seus dados antes de executar comandos potencialmente destrutivos (erros acontecem) :
#!/usr/bin/env python3
"""Move image files to their tag directories by creating hardlinks.
Usage: move-to-tag-dirs <image>...
"""
import json
import os
import sys
from subprocess import Popen, PIPE
TAGNAMES = ['TagsList', 'Keywords', 'Subject']
__version__ = '0.3.1'
def move_to_dirs(filename, dirs):
"""Move *filename* to *dirs* by creating hardlinks.
Create destination directories if they don't exist.
"""
for dirname in dirs:
os.makedirs(dirname, exist_ok=True)
dest_filename = os.path.join(dirname, os.path.basename(filename))
os.link(filename, dest_filename) # create hardlink
if dirs: # created at least one new link
os.unlink(filename) # remove old
if len(sys.argv) < 2:
sys.exit(__doc__) # print usage
command = ['exiftool', '-json'] + ['-' + t for t in TAGNAMES] + sys.argv[1:]
try:
process = Popen(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
except OSError as e:
sys.exit("error: can't start exiftool: " + str(e))
else:
output, errors = process.communicate()
if process.returncode != 0:
sys.exit("error: can't read tags info: exiftool exit code: %d: %s" % (
process.returncode, errors))
for metadata in json.loads(output):
# get first available tags list
dirs = next(filter(None, map(metadata.get, TAGNAMES)), [])
if isinstance(dirs, str): # single tag
dirs = [dirs]
try:
move_to_dirs(metadata['SourceFile'], dirs)
except OSError as e:
print("warning: failed to move %s to %s: %s" % (
metadata['SourceFile'], dirs, e), file=sys.stderr)
Salve-o em um arquivo chamado move-to-tag-dirs
em algum lugar em $PATH
. Certifique-se de que o arquivo tenha permissões executáveis:
$ chmod +x move-to-tag-dirs
Relacionados: Como executar um programa .py diretamente?
Em seguida, para mover todas as imagens para os diretórios de tags correspondentes, execute:
$ move-to-tag-dirs *.jpg *.png
Se você obtiver 'Argument list too long'
de erro, execute:
$ find . -maxdepth 1 -name \*.jpg -o -name \*.png -exec move-to-tag-dirs {} +
Veja Resolvendo “mv: lista de argumentos muito longa”?
Se você ignorar tratamento de erros, suporte a tags hierárquicas, suporte a caracteres incomuns em nomes de arquivos, tags, etc., o script poderia ser simplificado significativamente (talvez um shell script simples fosse suficiente nesse caso).