2

私が持っている種類のデータ (LDIF ファイル) を並べ替える方法をオンラインで探していましたが、探しているものがまったく見つかりませんでした。この並べ替えを実行するプログラムは既に存在しますが、非常に大きなデータ セットでは失敗します。私にとって非常に大きいのは、これらのブロックの約 2 GB 相当であり、6 GB の RAM が利用可能で、さらに数 GB のスワップがある場合でも、ldifsort.pl スクリプトを使用するとメモリが使い果たされます。そこで、データのブロックをハード ドライブに保存し、メモリ内のキーを並べ替えてから、ブロックを並べ替えた順序で再構築するプログラムを作成したいと考えています。そして、その言語を学ぼうとしているので、python3 を使用したいと思います。したがって、誰かが基本的な戦略や python3 でこれを行う具体的な方法について提案があれば、本当に助けていただければ幸いです。

LDAP データを含む大きなテキスト ファイルがあり、基本的に次の (非常に簡略化された) 形式です。

dn: Subscriber=UniqueName1@domain.com;RestOfTree=node1
groups: 1
permissions: 1
IsActive: FALSE
Barring: TRUE

dn: ProfileID=UniqueName1@domain.com;Subscriber=UniqueName1;RestOfTree=node1
groups: 1
permissions: 1
ServiceProfile: Lemur

dn: Subscriber=UniqueName2@domain.com;RestOfTree=node1
groups: 1
permissions: 1
IsActive: FALSE
Barring: TRUE

dn: ProfileID=UniqueName2@domain.com;Subscriber=UniqueName2;RestOfTree=node1
groups: 1
permissions: 1
ServiceProfile: Lemur

各サブスクライバーには、さらに 3 つのブロックが関連付けられています (私のコード例では、サブスクライバーに関連付けられている他の 1 つのブロックのみを示しています)。並べ替えが完了した後、4 つのブロックすべてをまとめておきたいと思います。

したがって、この順序で dn を読み取ると (dn に関連付けられているデータは簡潔にするために非表示になっています):

dn: Subscriber=UniqueName2@domain.com;RestOfTree=node
dn: ProfileID=UniqueName2@domain.com;Subscriber=UniqueName2;RestOfTree=node
dn: Subscriber=UniqueName4@domain.com;RestOfTree=node
dn: ProfileID=UniqueName4@domain.com;Subscriber=UniqueName4;RestOfTree=node
dn: Subscriber=UniqueName1@domain.com;RestOfTree=node
dn: Subscriber=UniqueName3@domain.com;RestOfTree=node
dn: ProfileID=UniqueName3@domain.com;Subscriber=UniqueName3;RestOfTree=node
dn: ProfileID=UniqueName1@domain.com;Subscriber=UniqueName1;RestOfTree=node

出力を次のようにしたいと思います。

dn: Subscriber=UniqueName1@domain.com;RestOfTree=node
dn: ProfileID=UniqueName1@domain.com;Subscriber=UniqueName1;RestOfTree=node
dn: Subscriber=UniqueName2@domain.com;RestOfTree=node
dn: ProfileID=UniqueName2@domain.com;Subscriber=UniqueName2;RestOfTree=node
dn: Subscriber=UniqueName3@domain.com;RestOfTree=node
dn: ProfileID=UniqueName3@domain.com;Subscriber=UniqueName3;RestOfTree=node
dn: Subscriber=UniqueName4@domain.com;RestOfTree=node
dn: ProfileID=UniqueName4@domain.com;Subscriber=UniqueName4;RestOfTree=node

私が考えていたのは、sqlite3を使用してpythonが読み取ったときにデータを保存し、次にpythonでキーをソートし、クエリを使用してsqliteからデータを再度抽出し、データをファイルに書き込むことでした。しかし、sqlite でキーを探すのに時間がかかりすぎるのではないかと心配しています。次に、データを挿入しているときにsqliteでデータをソートできると思ったのですが、sqliteはこれをサポートしていないようで、別のデータベースシステムがあるかどうかわかりません。

どんな助けや指示も大歓迎です。

データベース システムの代わりに GNU ソートを使用するという提案をしてくれた Zach に感謝します。これが私が彼の助けを借りて開発したソリューションです。

awk -f ldifformatter.awk LDAP データ ファイル*.ldif | 並べ替え -t \| -k1 | sed '1d;s/|/\n/g' > sorted.txt

ここで、ldifformatter.awk はすべての改行を「|」に置き換えます。ソートに使用される最上位の dn を除きます。

ありがとう、ラスティ

4

3 に答える 3

1

コマンドラインsortユーティリティは、非常に大きなテキスト ファイルを完全にメモリに読み込まずに並べ替えることができます (少なくとも、GNU バージョンでは可能です)。ただし、これを使用するには、各レコード (まとめて保持する必要があるすべてのもの) が 1 行に表示されるようにデータを再フォーマットする必要があります。レコードが次のようになっている場合:

dn: Subscriber=UniqueName1@domain.com;RestOfTree=node1|groups: 1|permissions: 1|IsActive: FALSE|Barring: TRUE||dn: ProfileID=UniqueName1@domain.com;Subscriber=UniqueName1;RestOfTree=node1|groups: 1|permissions: 1|ServiceProfile: Lemur

その後sort -t \| -k1、仕事をします。

sortデータを適切な形式で一時ファイルにストリーミングし、を使用して呼び出しsubprocess.check_call、元の形式を復元するプログラムを Python で作成できます。tmpfile.NamedTemporaryFile一時ファイルの作成に使用します。

于 2013-08-28T15:48:11.380 に答える
0

SQLite は本当にその役目を果たしていないのだろうか。とにかく、Mergesort などの外部ソート アルゴリズムを使用して、メモリ使用量を低く抑えることができます。

http://en.wikipedia.org/wiki/External_sorting

于 2013-08-28T15:47:43.130 に答える