[PYTHON] Ich habe verschiedene Dinge zur Unicode-Normalisierung von Amazon S3 ausprobiert (August 2016)

Ursprung

Ich habe eine Datei aus der Testumgebung meines Dienstes auf Amazon S3 hochgeladen und den Schlüssel angegeben, um die Metainformationen anzuzeigen. Ich konnte jedoch keine Übereinstimmung finden. Bei verschiedenen Suchvorgängen wurde die Unicode-Regelmäßigkeit aufgrund der Trübung des Dateinamens überprüft Ich bemerkte, dass ich in der Falle der Bekehrung gefangen war (ich wurde darauf aufmerksam gemacht).

Ich war ein wenig besorgt und beschloss, kurz zu untersuchen, wie der S3 in anderen Situationen behandelt wird.

… Das ist die Geschichte um August 2016. Ich weiß nicht, was jetzt los ist, aber ich werde den Artikel einmal veröffentlichen. Wenn das aktuelle wiedergegeben werden kann + Wenn klar wird, was unter Windows passieren wird, fügen Sie es hinzu / bearbeiten Sie es.

Rezension

Informationen zum Umgang mit Dateinamen unter Mac (HFS +) und Windows (NTFS) finden Sie auf den folgenden Seiten.

Zusammenfassen

Es scheint, dass.

Zusammenfassung und Schlussfolgerung

Zusammenfassung

--S3 gibt die Unicode-Normalisierungsmethode nicht an.

Außerdem werde ich die Ergebnisse der unten durchgeführten Experimente veröffentlichen.

No. Wie hochladen/Dateisystem Normalisierungsmethode Bemerkungen
1. HFS+ NFD(?) Mit Touch-Befehl erstellen
2. NTFS Nicht untersucht Erstellt im Explorer
3. Python AWS SDK(boto3) NFC / NFD / NFKC / NFKD
Der von Ihnen gewählte wird verwendet
Die alte Schriftart wird durch die neue ersetzt
4. bash(Mac) + aws s3 sync NFD 1.Datei
5. bash(Mac) + aws s3 cp NFC 1.Datei
6. Chrome(Mac, AWS-Konsole) NFD 1.Datei
7. Chrome(Win, AWS-Konsole) NFC 2.Datei

Ich denke, dass die alte Schriftart aufgrund der Bibliothek auf der Python-Seite zur neuen Schriftart in boto3 wird.

Fazit

――Ich denke, es ist besser, die Verwendung japanischer Dateinamen beim Hochladen von Dateien auf S3 zu beenden ――Es sollte beachtet werden, dass Sie die Schlüssel aufgrund des Unterschieds möglicherweise nicht finden können, selbst wenn Sie sie verwenden müssen. ―― Insbesondere aws-cli verhält sich je nach Situation unterschiedlich. Gehen Sie daher vorsichtig damit um.

Experiment

Alle Eimer werden der Einfachheit halber mit "passenden Namen" versehen.

Hochladen von Dateien mit AWS SDK für Python (Boto3)

Ich habe das folgende Programm vorbereitet und die Behandlung in S3 untersucht, wenn die Zeichenfolge durch NFC, NFD, NFKC, NFKD normalisiert wird.

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

import unicodedata

import boto3


FORMS = ['NFC', 'NFKC', 'NFD', 'NFKD']
STRINGS = [u"1_Zakoba", u"2_Flusskrebs", u"3_Pippi", u"4_㌠", u"5_Gott", u"6_{0}".format(unichr(0xfa19))]
BUCKET_NAME = 'Passender Name'

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()

Die Ergebnisse sind wie folgt.

s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFC/1_\u3056\u3053\u3070')
    NFC/1_Zakoba
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFC/2_\u30b6\u30ea\u30ac\u30cb')
    NFC/2_Flusskrebs
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFC/3_\uff8b\uff9f\uff6f\uff8b\uff9f')
    NFC/3_Pippi
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFC/4_\u3320')
    NFC/4_㌠
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFC/5_\u795e')
    NFC/5_Gott
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFC/6_\u795e')
    NFC/6_Gott
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFD/1_\u3055\u3099\u3053\u306f\u3099')
    NFD/1_Zakoba
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFD/2_\u30b5\u3099\u30ea\u30ab\u3099\u30cb')
    NFD/2_Flusskrebs
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFD/3_\uff8b\uff9f\uff6f\uff8b\uff9f')
    NFD/3_Pippi
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFD/4_\u3320')
    NFD/4_㌠
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFD/5_\u795e')
    NFD/5_Gott
s3.ObjectSummary(bucket_name='Passender Name', key=u'    NFD/6_\u795e')
    NFD/6_Gott
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKC/1_\u3056\u3053\u3070')
   NFKC/1_Zakoba
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKC/2_\u30b6\u30ea\u30ac\u30cb')
   NFKC/2_Flusskrebs
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKC/3_\u30d4\u30c3\u30d4')
   NFKC/3_Pippi
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKC/4_\u30b5\u30f3\u30c1\u30fc\u30e0')
   NFKC/4_Sun Team
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKC/5_\u795e')
   NFKC/5_Gott
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKC/6_\u795e')
   NFKC/6_Gott
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKD/1_\u3055\u3099\u3053\u306f\u3099')
   NFKD/1_Zakoba
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKD/2_\u30b5\u3099\u30ea\u30ab\u3099\u30cb')
   NFKD/2_Flusskrebs
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKD/3_\u30d2\u309a\u30c3\u30d2\u309a')
   NFKD/3_Pippi
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKD/4_\u30b5\u30f3\u30c1\u30fc\u30e0')
   NFKD/4_Sun Team
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKD/5_\u795e')
   NFKD/5_Gott
s3.ObjectSummary(bucket_name='Passender Name', key=u'   NFKD/6_\u795e')
   NFKD/6_Gott

Wenn Sie es so betrachten, können Sie sehen, dass das S3-Dateisystem nichts tut.

Obwohl es sich um ein Dateisystem handelt, ist der Name (Schlüssel) im Fall von S3 ursprünglich nur eine Art Metadaten, und dies ist wahrscheinlich die Haltung, ihn der Upload-Seite zu überlassen.

Beim Hochladen von Bash auf Mac mit aws-cli Teil 1

Erstens ist der Status der Datei.

$ 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_Flusskrebs
-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_Gott
-rw-r--r--  1 npoi  staff     0  8  2 23:08 6_Gott

Die Bestätigung aus dem interaktiven Modus von Python sieht auch so aus.

$ 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_Flusskrebs
[u'3_\uff8b\uff9f\uff6f\uff8b\uff9f'] 3_Pippi
[u'4_\u3320'] 4_㌠
[u'5_\u795e'] 5_Gott
[u'6_\ufa19'] 6_Gott
>>>

Es sieht aus wie NFD, aber 5 und 6 sind überraschend, wenn man sie tatsächlich sieht.

Lassen Sie uns dies mit aws s3 sync synchronisieren.

$ aws s3 sync ./sample/ s3://Passender Name/MAC_CLI
upload: sample/4_㌠ to s3://Passender Name/MAC_CLI/4_㌠
upload: sample/2_Zari Krabbe zu s3://Passender Name/MAC_CLI/2_Flusskrebs
upload: sample/6_Gott zu s3://Passender Name/MAC_CLI/6_Gott
upload: sample/5_Gott zu s3://Passender Name/MAC_CLI/5_Gott
upload: sample/1_Zakoba bis s3://Passender Name/MAC_CLI/1_Zakoba
upload: sample/.DS_Store to s3://Passender Name/MAC_CLI/.DS_Store
upload: sample/3_Pippi zu s3://Passender Name/MAC_CLI/3_Pippi

In diesem Zustand sah es so aus, als ich nach dem Hochladen aus dem Python SDK die in der Prüfung verwendete Funktion überprüfte.

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

Es scheint, dass die alte Schriftart ordnungsgemäß hochgeladen wurde, und es scheint, dass sie als HFS + NFD hochgeladen wurde.

Beim Hochladen von Bash auf Mac mit aws-cli Teil 2

Ich habe früher "aws s3 sync" verwendet, aber was ist mit "aws s3 cp"?

$ aws s3 cp 1_Zakoba s3://Passender Name/MAC_CLI2/
upload: 1_Zakoba bis s3://Passender Name/MAC_CLI2/1_Zakoba
$ aws s3 cp 2_Krabbe s3://Passender Name/MAC_CLI2/
upload: ./2_Zari Krabbe zu s3://Passender Name/MAC_CLI2/2_Flusskrebs
$ aws s3 cp 3_Pippi s3://Passender Name/MAC_CLI2/
upload: ./3_Pippi zu s3://Passender Name/MAC_CLI2/3_Pippi
$ aws s3 cp 4_㌠ s3://Passender Name/MAC_CLI2
upload: ./4_㌠ to s3://Passender Name/MAC_CLI2
$ aws s3 cp 4_㌠ s3://Passender Name/MAC_CLI2/
upload: ./4_㌠ to s3://Passender Name/MAC_CLI2/4_㌠
$ aws s3 cp 5_Gott s3://Passender Name/MAC_CLI2/
upload: ./5_Gott zu s3://Passender Name/MAC_CLI2/5_Gott
$ aws s3 cp 6_Gott s3://Passender Name/MAC_CLI2/
upload: ./6_Gott zu s3://Passender Name/MAC_CLI2/6_Gott

Überprüfen Sie dies auf die gleiche Weise mit einem Python-Programm.

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

Was für ein NFC.

Beim Hochladen von der Konsole mit Chrome auf dem Mac

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

Es sieht aus wie NFD. Es sieht genauso aus wie bei Verwendung von aws s3 sync.

Beim Hochladen von der Konsole mit Chrome unter Windows

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

NFC ...

Recommended Posts

Ich habe verschiedene Dinge zur Unicode-Normalisierung von Amazon S3 ausprobiert (August 2016)
Ich habe versucht, Amazon Glacier zu verwenden
Über verschiedene Codierungen von Python 3
Ich habe versucht, eine Umgebung von MkDocs unter Amazon Linux zu erstellen
[Satzklassifikation] Ich habe verschiedene Pooling-Methoden von Convolutional Neural Networks ausprobiert
Ich habe versucht, GrabCut von OpenCV zu verwenden
Ich habe versucht, mich über MCMC zu organisieren.
Ich habe versucht, die Beispielnachrichten zur Geschäftsintegration in Amazon Transcribe zu übertragen
Ich habe versucht, die logische Denkweise über Objektorientierung zusammenzufassen.
Ich habe versucht, verschiedene Muster von Datumszeichenfolgen in pandas.to_datetime einzugeben
Ich habe verschiedene Versionen der Python + OpenCV + FFmpeg-Umgebung auf dem Mac ausprobiert
[Lambda] Ich habe versucht, ein externes Python-Modul über S3 zu integrieren