2017-02-09 16 views
1

私は最近、unixシステム上の大気モデル(HYSPLIT)から数千のシェイプファイル出力と.dbfファイルを生成しました。コンバータtxt2dbfは、シェイプファイル属性テーブル(テキストファイル)を.dbfに変換するために使用されます。ファイルの.dbf出力と2つの問題があるため、次のようにdbfパッケージを使用して.dbfファイルを編集するときのBadDataError

残念ながら、何かが、(おそらくセパレータ/フィールド長エラー)間違っている:

  1. DBFの一部のフィールドはいけないデータが含まれていますそこにいる。このデータは近隣のフィールドから「流出」しています。
  2. 追加するフィールドが追加されているはずです(実際には、テキストファイルの最初のレコードのセクション「1000 201」から来ています)。

これは(dbview UNIXパッケージを使用して取得)出力DBFの最初のレコードの例です。

Trajnum : 1001 2
Yyyymmdd : 0111231 2
Time : 300
Level : 0.
1000 201:

は、ここに私が期待したものです:

Trajnum : 1000
Yyyymmdd : 20111231
Time : 2300
Level : 0.

別に、私はこれが再び起こらないようにする方法を見ていますが、理想的には、既存の.dbfファイルを修復できるようにしたいと考えています。残念なことに、テキストファイルはモデルの実行ごとに削除されるので、.dbfファイルを「修正する」唯一のオプションです。

上記の問題への私のアプローチは、以下のとおりです。

  1. はその後dbf.delete_fieldsを使用して、古い間違ったフィールドを削除し、dbf.add_fieldsdbf.write(Pythonパッケージをdbf)を使用して、新しい変数に存在しないフィールドから情報を抽出します。
  2. 不要な追加フィールドを削除します。

これは私が試したものです:

​​

をしかし、これは次のエラーを生成します。

dbf.ver_2.BadDataError: record data is not the correct length (should be 31, not 30) 

txt2dbf変換であったことが明らかに問題を考えると、私は」レコードのデータ長に誤りがあるのは驚きではありません。しかし、これは、ファイルが完全に壊れていて、必要な情報を抽出できないことを意味しますか(私はそれが存在することがわかるので、イライラしています)?


EDIT:

のではなく、ファイルの.dbf「悪い」を編集しようとすると、1に、より良いアプローチが悪いのファイルからテキストに必要なデータを抽出しそうですし、その後2書き込み新しいdbfに移動します。 (Ethan Furmanのコメント/回答を参照)。


EDIT:

故障の例。ここで見つけることができますから、私は/修正データを回復する必要があるDBFファイル:

https://www.dropbox.com/s/9y92f7m88a8g5y4/p0001120110.dbf?dl=0

作成された障害のあるDBFファイルは、ここで見つけることができ、そこから.txtファイルの例:

https://www.dropbox.com/s/d0f2c0zehsyy8ab/attTEST.txt?dl=0

+0

dbfファイルからテキストファイルを再構築して再変換する方が簡単かもしれません - 試してみましたか? –

+0

ありがとう、イーサン。いいえ、私はこれを試してみることは考えていませんでした。それは脱獄カードになる可能性があります。これは、 'txt2dbf -C7 -C9 -C5を使った' txt2dbf'コマンドを逆転させるケースでしょうか? -C9 -d、-d、-d、file.att file.dbf'から 'dbf2txt -C7 -C9 -C5 -C9 -d、-d、-d、file.dbf file.att' –

+0

私は持っていませんそれらのコマンドを使用して私は知らない。たとえば、最後の数文字が空白文字であっても、C9フィールドには9文字が含まれているため、特別な注意が必要になります。あなたの入力ファイルがどのように見えるかによって、これはうまくいくかもしれません - おそらく、あなたは入力テキストファイルのいくつかの例の行を投稿することができますか? –

答えて

0

は、データを修正し、元のテキストファイルを再作成するには、このスニペットは役立つはず:

import dbf 

table = dbf.Table('/path/to/scramble/table.dbf') 
with table: 
    fixed_data = [] 
    for record in table: 
     # convert to str/bytes while skipping delete flag 
     data = record._data[1:].tostring() 
     trajnum = data[:4] 
     ymd = data[4:12] 
     time = data [12:16] 
     level = data[16:].strip() 
     fixed_data.extend([trajnum, ymd, time, level]) 

new_file = open('repaired_data.txt', 'w') 
for line in fixed_data: 
    new_file.write(','.join(line) + '\n') 

をすべてを想定すると、あなたは手の込んだ得ることができる。もちろん、

raw_data = open('some_text_file.txt').read().split('\n') 
final_table = dbf.Table(
     'dest_table.dbf', 
     'trajnum C(4); yyyymmdd C(8); time C(4); level C(9)', 
     ) 
with final_table: 
    for line in raw_data: 
     fields = line.split(',') 
     final_table.append(tuple(fields)) 

# table has been populated and closed 

と:データファイルは、あなたのサンプル(ビッグ IFデータが埋め込まれていないコンマを持っていないもの)は、このラフなコードは、DBFSにあなたのテキストファイルを翻訳に役立つはずのように見えます実際の日付と数字フィールドを使用したい場合:

+0

これは本当に有望なようです - 上記のコードをいただきありがとうございます。私は、元のテキストを回復するために最初のブロックを実行しようとしましたが、 'AttributeError: 'array.array'オブジェクトに属性 'strip'がありません。 'data [16:]。strip()'が使用されているか、よく知られているエラー 'dbf.ver_2.BadDataError:.strip()の部分が出るときに、レコードのデータが正しい長さではありません(31でなく30でなければなりません)。 –

+0

(別名、)私はサンプルのテキストファイルで2番目のコードブロックを実行しようとしましたが、次のエラーが発生します: 'dbf.ver_2.DbfError:入力データの値が多すぎます。 –

+0

ああ、ごめんなさい。更新されたスニペット。 –

関連する問題