[PYTHON] J'ai essayé diverses choses sur la normalisation Unicode d'Amazon S3 (août 2016)

Origine

J'ai téléchargé un fichier sur Amazon S3 à partir de l'environnement de test de mon service et spécifié la clé pour voir les méta-informations, mais je n'ai pas pu trouver de correspondance, et lorsque j'ai recherché différemment, la régularité Unicode en raison de la turbidité dans le nom du fichier J'ai remarqué que j'étais pris au piège de la conversion (j'en ai été mis au courant).

J'étais un peu inquiet, alors j'ai décidé d'étudier brièvement comment le S3 est traité dans d'autres situations.

… C'est l'histoire d'août 2016. Je ne sais pas ce qui se passe maintenant, mais je publierai l'article une fois. Si l'actuel peut être reflété + S'il devient clair ce qui va se passer sous Windows, ajoutez / modifiez.

la revue

Pour la gestion des noms de fichiers sur Mac (HFS +) et Windows (NTFS), reportez-vous aux pages ci-dessous.

Résumer

--Sur Mac, une méthode de normalisation unique basée sur NFD

Il paraît que.

Sommaire et conclusion

Résumé

--S3 ne spécifie pas la méthode de normalisation Unicode.

Aussi, je publierai les résultats des expériences menées ci-dessous.

No. Comment télécharger/Système de fichiers Méthode de normalisation Remarques
1. HFS+ NFD(?) Créer avec la commande tactile
2. NTFS Non étudié Créé dans Explorer
3. SDK Python AWS(boto3) NFC / NFD / NFKC / NFKD
Celui que vous choisissez sera utilisé
L'ancienne police est remplacée par la nouvelle police
4. bash(Mac) + aws s3 sync NFD 1.Fichier
5. bash(Mac) + aws s3 cp NFC 1.Fichier
6. Chrome(Mac, console AWS) NFD 1.Fichier
7. Chrome(Win, console AWS) NFC 2.Fichier

Je pense que l'ancienne police devient la nouvelle police de boto3 à cause de la bibliothèque côté Python.

Conclusion

――Je pense qu'il vaut mieux arrêter d'utiliser les noms de fichiers japonais lors du téléchargement de fichiers sur S3 ――Il convient de noter que même si vous devez l'utiliser, vous ne pourrez peut-être pas faire correspondre les touches en raison de la différence. En particulier, aws-cli se comporte différemment selon la situation, vous devez donc être prudent lorsque vous le manipulez.

Expérience

Tous les seaux reçoivent des «noms appropriés» pour plus de commodité.

Téléchargement de fichiers avec AWS SDK for Python (Boto3)

J'ai préparé le programme suivant et étudié la manipulation dans S3 lorsque la chaîne de caractères est normalisée par NFC, NFD, NFKC, NFKD.

#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import unicodedata

import boto3


FORMS = ['NFC', 'NFKC', 'NFD', 'NFKD']
STRINGS = [u"1_Zakoba", u"2_écrevisse", u"3_Pippi", u"4_㌠", u"5_Dieu", u"6_{0}".format(unichr(0xfa19))]
BUCKET_NAME = 'Nom approprié'

def make_files():
    session = boto3.session.Session()
    s3 = session.resource("s3")

    for form in FORMS:
        for string in STRINGS:
            key = u"{0:>7}/{1}".format(form, string)
            key = unicodedata.normalize(form, key)
            obj = s3.Object(BUCKET_NAME, u"{0}".format(key))
            obj.put(Body='test')


def list_files():
    session = boto3.session.Session()
    s3 = session.resource("s3")

    bucket = s3.Bucket(BUCKET_NAME)
    for i in bucket.objects.all():
        print i
        print i.key.encode("utf-8")


if __name__ == "__main__":
    make_files()
    list_files()

Les résultats sont les suivants.

s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFC/1_\u3056\u3053\u3070')
    NFC/1_Zakoba
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFC/2_\u30b6\u30ea\u30ac\u30cb')
    NFC/2_écrevisse
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFC/3_\uff8b\uff9f\uff6f\uff8b\uff9f')
    NFC/3_Pippi
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFC/4_\u3320')
    NFC/4_㌠
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFC/5_\u795e')
    NFC/5_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFC/6_\u795e')
    NFC/6_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFD/1_\u3055\u3099\u3053\u306f\u3099')
    NFD/1_Zakoba
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFD/2_\u30b5\u3099\u30ea\u30ab\u3099\u30cb')
    NFD/2_écrevisse
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFD/3_\uff8b\uff9f\uff6f\uff8b\uff9f')
    NFD/3_Pippi
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFD/4_\u3320')
    NFD/4_㌠
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFD/5_\u795e')
    NFD/5_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'    NFD/6_\u795e')
    NFD/6_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKC/1_\u3056\u3053\u3070')
   NFKC/1_Zakoba
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKC/2_\u30b6\u30ea\u30ac\u30cb')
   NFKC/2_écrevisse
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKC/3_\u30d4\u30c3\u30d4')
   NFKC/3_Pippi
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKC/4_\u30b5\u30f3\u30c1\u30fc\u30e0')
   NFKC/4_Équipe Sun
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKC/5_\u795e')
   NFKC/5_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKC/6_\u795e')
   NFKC/6_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKD/1_\u3055\u3099\u3053\u306f\u3099')
   NFKD/1_Zakoba
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKD/2_\u30b5\u3099\u30ea\u30ab\u3099\u30cb')
   NFKD/2_écrevisse
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKD/3_\u30d2\u309a\u30c3\u30d2\u309a')
   NFKD/3_Pippi
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKD/4_\u30b5\u30f3\u30c1\u30fc\u30e0')
   NFKD/4_Équipe Sun
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKD/5_\u795e')
   NFKD/5_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'   NFKD/6_\u795e')
   NFKD/6_Dieu

Si vous regardez les choses de cette façon, vous pouvez voir que le système de fichiers S3 ne fait rien.

À l'origine, même s'il s'agit d'un système de fichiers, dans le cas de S3, le nom (clé) n'est également qu'une sorte de métadonnées, et c'est probablement la position de le laisser du côté du téléchargement.

Lors du téléchargement depuis Bash sur Mac à l'aide de aws-cli Partie 1

Le premier est le statut du fichier.

$ ls -l
-rw-r--r--  1 npoi  staff     0  8  2 21:43 1_Zakoba
-rw-r--r--  1 npoi  staff     0  8  2 21:43 2_écrevisse
-rw-r--r--  1 npoi  staff     0  8  2 23:42 3_Pippi
-rw-r--r--  1 npoi  staff     0  8  2 21:43 4_㌠
-rw-r--r--  1 npoi  staff     0  8  2 23:42 5_Dieu
-rw-r--r--  1 npoi  staff     0  8  2 23:08 6_Dieu

De plus, la confirmation du mode interactif de Python ressemble à ceci.

$ python
Python 2.7.11 (default, Dec  5 2015, 14:44:53)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.1.76)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> for i in os.listdir("."):
...     print [i.decode('utf-8')],i
...
[u'.DS_Store'] .DS_Store
[u'1_\u3055\u3099\u3053\u306f\u3099'] 1_Zakoba
[u'2_\u30b5\u3099\u30ea\u30ab\u3099\u30cb'] 2_écrevisse
[u'3_\uff8b\uff9f\uff6f\uff8b\uff9f'] 3_Pippi
[u'4_\u3320'] 4_㌠
[u'5_\u795e'] 5_Dieu
[u'6_\ufa19'] 6_Dieu
>>>

Cela ressemble à NFD, mais 5 et 6 sont surprenants quand vous les voyez réellement.

Synchronisons cela avec ʻaw s3 sync`.

$ aws s3 sync ./sample/ s3://Nom approprié/MAC_CLI
upload: sample/4_㌠ to s3://Nom approprié/MAC_CLI/4_㌠
upload: sample/2_Crabe de Zari à s3://Nom approprié/MAC_CLI/2_écrevisse
upload: sample/6_Dieu à s3://Nom approprié/MAC_CLI/6_Dieu
upload: sample/5_Dieu à s3://Nom approprié/MAC_CLI/5_Dieu
upload: sample/1_Zakoba à s3://Nom approprié/MAC_CLI/1_Zakoba
upload: sample/.DS_Store to s3://Nom approprié/MAC_CLI/.DS_Store
upload: sample/3_Pippi à s3://Nom approprié/MAC_CLI/3_Pippi

Dans cet état, lorsque j'ai vérifié avec la fonction utilisée dans la vérification après le téléchargement à partir du SDK Python, cela ressemblait à ceci.

s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI/1_\u3055\u3099\u3053\u306f\u3099')
MAC_CLI/1_Zakoba
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI/2_\u30b5\u3099\u30ea\u30ab\u3099\u30cb')
MAC_CLI/2_écrevisse
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI/3_\uff8b\uff9f\uff6f\uff8b\uff9f')
MAC_CLI/3_Pippi
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI/4_\u3320')
MAC_CLI/4_㌠
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI/5_\u795e')
MAC_CLI/5_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI/6_\ufa19')
MAC_CLI/6_Dieu

Il semble que l'ancienne police a été téléchargée correctement, et il semble qu'elle soit téléchargée en tant que HFS + NFD.

Lors du téléchargement depuis Bash sur Mac à l'aide de aws-cli Partie 2

J'ai utilisé ʻaws s3 sync plus tôt, mais qu'en est-il de ʻaws s3 cp?

$ aws s3 cp 1_Zakoba s3://Nom approprié/MAC_CLI2/
upload: 1_Zakoba à s3://Nom approprié/MAC_CLI2/1_Zakoba
$ aws s3 cp 2_Crabe s3://Nom approprié/MAC_CLI2/
upload: ./2_Crabe de Zari à s3://Nom approprié/MAC_CLI2/2_écrevisse
$ aws s3 cp 3_Pippi s3://Nom approprié/MAC_CLI2/
upload: ./3_Pippi à s3://Nom approprié/MAC_CLI2/3_Pippi
$ aws s3 cp 4_㌠ s3://Nom approprié/MAC_CLI2
upload: ./4_㌠ to s3://Nom approprié/MAC_CLI2
$ aws s3 cp 4_㌠ s3://Nom approprié/MAC_CLI2/
upload: ./4_㌠ to s3://Nom approprié/MAC_CLI2/4_㌠
$ aws s3 cp 5_Dieu s3://Nom approprié/MAC_CLI2/
upload: ./5_Dieu à s3://Nom approprié/MAC_CLI2/5_Dieu
$ aws s3 cp 6_Dieu s3://Nom approprié/MAC_CLI2/
upload: ./6_Dieu à s3://Nom approprié/MAC_CLI2/6_Dieu

Vérifiez avec un programme Python de la même manière.

s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI2/1_\u3056\u3053\u3070')
MAC_CLI2/1_Zakoba
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI2/2_\u30b6\u30ea\u30ac\u30cb')
MAC_CLI2/2_écrevisse
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI2/3_\uff8b\uff9f\uff6f\uff8b\uff9f')
MAC_CLI2/3_Pippi
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI2/4_\u3320')
MAC_CLI2/4_㌠
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI2/5_\u795e')
MAC_CLI2/5_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_CLI2/6_\ufa19')
MAC_CLI2/6_Dieu

Quel NFC.

Lors du téléchargement depuis la console à l'aide de Chrome sur Mac

s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_GUI/1_\u3055\u3099\u3053\u306f\u3099')
MAC_GUI/1_Zakoba
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_GUI/2_\u30b5\u3099\u30ea\u30ab\u3099\u30cb')
MAC_GUI/2_écrevisse
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_GUI/3_\uff8b\uff9f\uff6f\uff8b\uff9f')
MAC_GUI/3_Pippi
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_GUI/4_\u3320')
MAC_GUI/4_㌠
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_GUI/5_\u795e')
MAC_GUI/5_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'MAC_GUI/6_\ufa19')
MAC_GUI/6_Dieu

Cela ressemble à NFD. Cela a la même apparence que lors de l'utilisation de ʻaws s3 sync`.

Lors du téléchargement depuis la console à l'aide de Chrome sous Windows

s3.ObjectSummary(bucket_name='Nom approprié', key=u'WIN_GUI/1_\u3056\u3053\u3070')
WIN_GUI/1_Zakoba
s3.ObjectSummary(bucket_name='Nom approprié', key=u'WIN_GUI/2_\u30b6\u30ea\u30ac\u30cb')
WIN_GUI/2_écrevisse
s3.ObjectSummary(bucket_name='Nom approprié', key=u'WIN_GUI/3_\uff8b\uff9f\uff6f\uff8b\uff9f')
WIN_GUI/3_Pippi
s3.ObjectSummary(bucket_name='Nom approprié', key=u'WIN_GUI/4_\u3320')
WIN_GUI/4_㌠
s3.ObjectSummary(bucket_name='Nom approprié', key=u'WIN_GUI/5_\u795e')
WIN_GUI/5_Dieu
s3.ObjectSummary(bucket_name='Nom approprié', key=u'WIN_GUI/6_\ufa19')
WIN_GUI/6_Dieu

NFC ...

Recommended Posts

J'ai essayé diverses choses sur la normalisation Unicode d'Amazon S3 (août 2016)
J'ai essayé d'utiliser Amazon Glacier
À propos de divers encodages de Python 3
J'ai essayé de créer un environnement de MkDocs sur Amazon Linux
[Classification des phrases] J'ai essayé différentes méthodes de mise en commun des réseaux de neurones convolutifs
J'ai essayé d'utiliser GrabCut d'OpenCV
J'ai essayé de m'organiser à propos de MCMC.
J'ai essayé de transcrire les actualités de l'exemple d'intégration commerciale sur Amazon Transcribe
J'ai essayé de résumer la manière logique de penser l'orientation objet.
J'ai essayé différents modèles de chaînes de date à saisir dans pandas.to_datetime
J'ai essayé différentes versions de l'environnement Python + OpenCV + FFmpeg sur Mac
[Lambda] J'ai essayé d'incorporer un module externe de python via S3