AWK может это сделать? Фиксированные с полями, горизонтальные и вертикальные записи смешаны

У меня есть следующая структура записи:

ID            Bezeichner                 OGD-Kurzname                     CKAN Feld         Anzahl
          Bezeichnung der
 2                                        schema_name             extras:schema_name           1
         Metadatenstruktur
Definition        Name der Metadatenstruktur
                  Die Angabe für OGD Metadaten ist optional, sollte aber wenn möglich
                  erfolgen. Bei einer Adaptierung der OGD Metadatenstruktur wird eine
Erläuterung
                  konsistente Metadatenführung erleichtert. Dieses Metadatenelement sollte
                  automatisch vom System (Software) befüllt werden
Beispiel          OGD Austria Metadata 2.0
ON A              1.4
2270:2010
ON/EN/ISO         mdStanName (10)
19115:2003
RDF property      dcterms:alternative
Definition        OGD Austria Metadata 2.0.
Englisch

ID            Bezeichner                 OGD-Kurzname                     CKAN Feld         Anzahl
            Sprache des                                                    extras:
 3                                      schema_language                                        1
          Metadatensatzes                                           schema_language
Definition        ISO 639-2 dreistelliger ISO Sprachcode für den Metadatensatz
                  Sprache in welcher der Metadatensatz erstellt wurde. Dieses
Erläuterung
                  Metadatenelement sollte automatisch vom System (Software) befüllt werden
Beispiel          ger
ON A              1.2
2270:2010
ON/EN/ISO         mdLang (3)
19115:2003
RDF property      dcterms:language
Definition        Metadata language, always ger (German)
Englisch

Я хотел бы разделить его на эту структуру:

2|Bezeichnung der Metadatenstruktur|schema_name|extras:schema_name|1|Name der Metadatenstruktur|Die Angabe für OGD Metadaten ist optional, sollte aber wenn möglich erfolgen. Bei einer Adaptierung der OGD Metadatenstruktur wird eine konsistente Metadatenführung erleichtert. Dieses Metadatenelement sollte automatisch vom System (Software) befüllt werden|OGD Austria Metadata 2.0|1.4|mdStanName (10)|dcterms:alternative|OGD Austria Metadata 2.0.
3|Sprache des Metadatensatzes|schema_language|extras:schema_language|1|ISO 639-2 dreistelliger ISO Sprachcode für den Metadatensatz|Sprache in welcher der Metadatensatz erstellt wurde. Dieses Metadatenelement sollte automatisch vom System (Software) befüllt werden|ger|1.2|mdLang (3)|dcterms:language|Metadata language, always ger (German)

Чтобы сделать это более очевидным, вот раскрашенный скриншот, разбросанный по полям. Желтым цветом отмечены поля заголовков, мне не нужны, оранжевыми обязательны поля: http://i.imgur.com/PwG6g.png


person JohnDoe    schedule 17.12.2012    source источник


Ответы (2)


Анализ извлеченного текста из PDF никогда не бывает идеальным. Но если вы в отчаянии (и, возможно, немного сумасшедшем), вы можете попробовать написать свой собственный пейзер. Хитрость заключается в правильном извлечении данных в первую очередь. Поэтому я проигнорировал файл, на который вы ссылаетесь в комментариях ниже, и перешел прямо к источнику. Затем вы можете использовать pdftotext для выполнения извлечения. Вот что я сделал:

Шаг 1, получите файл:

wget http://www.data.gv.at/wp-content/uploads/2012/10/OGD-Metadaten_2_1_2012_10.pdf

Шаг 2, преобразуйте его:

pdftotext OGD-Metadaten_2_1_2012_10.pdf

Шаг 3, проанализируйте его:

Беги как:

awk -f script.awk OGD-Metadaten_2_1_2012_10.txt

Содержание script.awk:

BEGIN {
    RS="\nID\n"
    FS="\n"; OFS="|"

    a["Bezeichner"]; a["OGD-Kurzname"]; a["CKAN Feld"]
    a["Anzahl"]; a["Definition"]; a["Erläuterung"]
    a["Beispiel"]; a["ON A 2270:2010"]
    a["ON/EN/ISO 19115:2003"]; a["RDF property"]
    a["Definition Englisch"]
}

NR>2 {
    for (i=1;i<=NF;i++) {

        l = (l ? l (l ~ /^extras:$/ ? "" : " ") : "") $i

        if ($(i+1) == "" ) {
            if (l in a) {
                l = ""
            }
            else if (l != "") {
                c = (c ? c OFS : "") l
                n++
                l = ""
            }
        }
        if (n == 12) {
            print (c ~ /^[0-9]/ ? c : "ERROR: BAD RECORD")
            c = n = ""
            next
        }
    }
}

Полученные результаты:

1|Eindeutiger Identifikator|metadata_identifier|extras:metadata_identifier|1|Eindeutiger Identifikator für den Metadatensatz. Der Eintrag beschreibt die eindeutige Identifikation für einen Metadatensatz. Es sollte eine UUID (nach RFC:4122) gewählt werden.|Der Identifikator soll automatisch vom System (Software) generiert werden. Falls dieser vorhanden ist (Harvesten bestehender Metadatensätze) muss dieser übernommen werden.|550e8400-e29b-11d4-a716-446655441234|1.1|mdFileID (2)|dcterms:identifier|Unique Identifier of metadata. Should the a UUID conforming to RFC:4122
5|Datum des Metadatensatzes|metadata_modified|extras:metadata_modified|1|Datum, an dem der Metadatensatz erzeugt bzw. aktualisiert wurde. Die Datumsangabe erfolgt gemäß ÖNORM ISO 8601 YYYY-MM-DD.|Datum, an dem der Metadatensatz erzeugt bzw. aktualisiert wurde. Dieses Metadatenelement sollte automatisch vom System (Software) befüllt werden. Wird für eine inkrementelle Aktualisierung (Harvesten) in einem Metadatenverbund benötigt.|2011-05-22|1.6|mdDateSt (9)|dcterms:issued|Metadata creation or update timestamp. Specification according to ÖNORM ISO 8601 as YYYY-MM-DD
8|Titel des Metadatensatzes|title|title|1|Titel des beschriebenen Metadatensatzes.|Titel des beschriebenen Metadatensatzes.|Schulstandorte, Pendlerstatistik Linz 2010|2.1.1|resTitle (360)|dcterms:title (mit language tag "de")|Resource title
9|Beschreibung|description|notes|1|Inhaltliche Beschreibung des Datensatzes bzw. Dienstes.|Kurze inhaltliche Beschreibung des Datensatzes bzw. Dienstes für BenutzerInnen.|Hauptwohnsitzbevölkerung der Stadt Linz für das Jahr 2010 gruppiert nach Geschlecht, Alter etc..|2.2|idAbs (25)|dcterms:abstract|Description of the resources content.
10|Kategorie|categorization|extras:categorization[“…“,“…“]|N|Kategorisierung des Datensatzes bzw. Dienstes. Vorgegebenes Kategorienschema für Österreich, siehe Anhang b).|Es muss die Zuordnung des Datensatzes bzw. Dienstes an das vorgegebene Kategorienschema durchgeführt und zur Anwendung gebracht werden. Mehrfachzuordnungen sind möglich.|Gesundheit|2.7.1 & 2.7.2|keyword (53) & thesaName (55)|dcat:theme|Categorisation of the resources content.
11|Schlagworte|keywords|tags|N|Beschlagwortung des Datensatzes bzw. Dienstes.|Beschlagwortung des Datensatzes bzw. Dienstes.|Habitatmodell, Braunbär, Ursus arctos|2.7.1|keyword (53)|dcat:keyword|Key words describing the resource
14|Datensatz oder Dienst Link|resource_url|resources:url|N|URL für den Zugriff auf den Datensatz oder Dienst|URL für den Zugriff auf den Datensatz oder Dienst. Die Angabe zielt auf unterschiedliche Daten- und Dienstformate ab. Es muss sichergestellt sein, dass ausschließlich vergleichbare Information in einer Datensatz/Dienstegruppe abgebildet werden. Im Zweifelsfall sollen eigenständige Metadatensätze angelegt werden.|http://www.wien.gv.at/statistik/ogd/vie-district-pop-foreignborn.csv|6.1.4.1.1|linkage (397)|dcat:accessURL|URL to the resource
15|Datensatz oder Dienst Format|resource_format|resources:format|N|Angabe zum Format des Datensatzes oder Dienstes. Diese ist als Dateiformat, Download- oder Service- Link anzugeben. Liste von OGD Formaten, siehe Anhang a).|OGD-Formate sollten grundsätzlich offene, maschinenlesbare Formate sein. Das bedeutet, dass publizierte Spezifikationen existieren und die Formate ohne rechtliche Einschränkungen genutzt werden können. Die Angabe soll ohne Punkt und in Kleinbuchstaben erfolgen.|csv|6.1.2.1|formatName (285)|dcterms:format|Specification of the resource. This may be a file type, download or service link. List of defined OGD formats in Appendix a).
19|Datenverantwortliche Stelle|maintainer|maintainer|1|Bezeichnung bzw. Name der für den Datensatzes oder Dienst zuständigen Organisation bzw. Person|Bezeichnung bzw. Name der für den Datensatzes oder Dienst zuständigen Organisation bzw. Person, kann in kleinen Organisationen gleichzeitig die veröffentlichende Stelle sein.|Magistrat Wien - Magistratsabteilung 33 - Wien Leuchtet|2.5.1 / 2.5.2|rpIndName (375) / rpOrgName (376)|dcelements:creator|Name of the person or entity responsible for the resource.
21|Lizenz|license|license|1|Rechtliche Nutzungsinformationen für die Verwendung des Datensatzes oder Dienstes.|Angabe der Lizenzform für den Datensatz oder den bereitgestellten Dienst. Bei OGD Daten bezieht sich dies auf Creative Commons "Namensnennung 3.0 Österreich (CC BY 3.0) ".|Namensnennung 3.0 Österreich (CC BY 3.0)|2.8.1.1|othConsts (72)|dcterms:license (sollte URI des Lizenzdokuments sein)|Legal information concerning the usage of the resource
24|Zeitliche Ausdehnung (Anfang)|begin_datetime|extras:begin_datetime|1|Definition Erläuterung Beispiel|Element zur Erfassung des Beginns der Gültigkeit eines Datensatzes oder Dienstes. Element zur zeitlichen Erfassung eines Datensatzes oder Dienstes. Die Angabe des Zeitpunktes erfolgt in folgender Form YYYY-MM-DDThh:mm:ss. TM_Primitive (nach ON EN 8601 bzw. ON EN ISO 19108). 2008-12-23T22:30:12|2.9.6.2.1|exTemp (351)|dcterms:temporal|Date specifying valid from of the resource according to ON EN 8601 or ON EN ISO 19108 respectively.|ID … laufende, eindeutige Nummerierung im OGD-Metadatenkatalog Österreich Anzahl… 1= Single-Value-Feld N=Multi-Value-Feld
16|Datensatz oder Dienst Bezeichner|resource_name|resources:name|N|Bezeichner für den einzelnen Datensatz bzw. Dienst. Das Attribut korrespondiert mit dem Metadaten – Datensatz oder Dienst Link (ID 14).|CKAN verwendet dieses optionale Element als Bezeichner für die URL, die auf den Datensatz oder Dienst zeigt.|Hauptwohnsitzbevölkerung|2.1.1 + 6.1.2.1|-|rdfs:literal|Specifier for the single resource link within a metadata sheet. Will be used as an end user friendly text instead of the resource link.
2|Bezeichnung der Metadatenstruktur|schema_name|extras:schema_name|1|Name der Metadatenstruktur|Die Angabe für OGD Metadaten ist optional, sollte aber wenn möglich erfolgen. Bei einer Adaptierung der OGD Metadatenstruktur wird eine konsistente Metadatenführung erleichtert. Dieses Metadatenelement sollte automatisch vom System (Software) befüllt werden|OGD Austria Metadata 2.0|1.4|mdStanName (10)|dcterms:alternative|OGD Austria Metadata 2.0.
3|Sprache des Metadatensatzes|schema_language|extras:schema_language|1|ISO 639-2 dreistelliger ISO Sprachcode für den Metadatensatz|Sprache in welcher der Metadatensatz erstellt wurde. Dieses Metadatenelement sollte automatisch vom System (Software) befüllt werden|ger|1.2|mdLang (3)|dcterms:language|Metadata language, always ger (German)
4|Character Set Code des Metadatensatzes|schema_characterset|extras:schema_characterset|1|Characterset Code zur Beschreibung des Metadatensatzes nach ISO\IEC 10646-1|Für eine europäische Integration wird dieses Metadatenelement zwingend gebraucht, da eine Zusammenführung sonst nicht möglich ist. Dieses Metadatenelement sollte automatisch vom System (Software) befüllt werden.|utf8|1.3|mdC (4)|cnt:characterEncoding|Metadata payload character encoding, always utf8
6|Weiterführende Metadaten|metadata_linkage|extras:metadata_linkage|N|URL zu erweiterten Metadaten des Datensatzes bzw. Dienstes|URL zur weiteren ausführlicheren Beschreibung der Metadaten. Optional. Der originäre Metadaten Link ist anzugeben. Links auf zusätzliche Informationen in anderen Metadatenkatalogen können angeführt werden.|http://data.wien.gv.at/katalog/bevoelkerung-geburtsbundesland-wien.html|1.7.11|linkage (397)|dcat:dataDictionary|URL providing further descriptive metadata
12|Attributbeschreibung|attribute_description|extras:attribute_description|1|Beschreibung der Attributinformation des Datensatzes bzw. Dienstes|Menschenlesbare Beschreibung der Bedeutung der Datenfelder in einem Datensatz bzw. Dienst|ADRESSE: Adresse (Straßenname, Orientierungsnummer); OEFFNUNGSZEITEN1-6: Öffnungszeiten; TELEFON: Telefonnummer, DISTRICT_CODE: Gemeindebezirkskennzahl, ACCOUNTS_TRANSFER: Laufende Transferzahlungen|2.11.3 & 2.11.4|ISO 19110:2005|memberName (4.1) & definition (4.2)|dcterms:description
13|Bezeichner Kontaktseite der datenverantwortlichen Stelle|maintainer_link|extras:maintainer_link|1|Kontaktseite der datenverantwortlichen Stelle|URL zur daten- bzw. dienstverantwortlichen Stelle|http://www.wien.gv.at/freizeit/bildungjugend/|6.1.1.1.6|Linkage (397)|dcterms:creator|URL to the dataset maintainig entity
17|Datensatz oder Dienst Veröffentlichungsdatum|resource_created|resources:created|1|Datum der Veröffentlichung des Datensatzes oder Dienstes.|Beschreibt den Zeitpunkt der Veröffentlichung der Daten (z.B. das Datum, an dem der Datensatz oder Dienst auf der Website der Behörde verfügbar gemacht wurde).|2011-03-21 ( YYYY-MM-DD)|2.1.3.1 & 2.1.3.2|refDate (394) & refDateType (395)|dcterms:issued|Resource publication timestamp
18|Datensatz oder Dienst Änderungsdatum|resource_lastmodified|resources: last_modified|1|Datum der letzten Aktualisierung des Datensatzes oder Dienstes.|Letztes Aktualisierungsdatum des Datensatzes oder Dienstes.|2012-01-15 ( YYYY-MM-DD )|2.1.3.1 & 2.1.3.2|refDate (394) & refDateType (395)|dcterms:modified|Resource last update timestamp
20|Veröffentlichende Stelle|publisher|extras:publisher|1|Bezeichnung bzw. Name der für den Metadatensatz zuständigen Organisation bzw. Person|Bezeichnung bzw. Name der für den Metadatensatz zuständigen Organisation bzw. Person|Magistrat Wien - Abteilung 53 - Presse- und Informationsdienst|2.5.1 / 2.5.2|rpIndName (375) / rpOrgName (376)|dcelements:publisher|Name of the publishing entity or person
22|Geographische Abdeckung/Lage|geographic_toponym|extras:geographic_toponym|1|Geographische Ortsidentifikation eines Datensatzes oder Dienstes|Menschenlesbare Beschreibung der räumlichen Lage eines Datensatzes oder Dienstes|Linz|2.9.6.1.3.1.1|identCode (207)|dcterms:description|Human-readable description of the resources spatial context
23|Geographische Ausdehnung|geographic_bbox|extras:geographic_bbox|1|Dokumentation der geographischen Ausdehnung eines Datensatzes mit der Definition eines umrahmenden Rechtecks.|Beschreibung der räumlichen Ausdehnung eines Datensatzes mit einem umschreibenden Rechteck. Die Angabe erfolgt im Koordinatensystem EPSG:4326 (WGS84) mit einer Mindestgenauigkeit von zwei Dezimalstellen in einer "Well Known Text String" Repräsentation. POLYGON (Rechtswert_min Hochwert_min, Rechtswert_max Hochwert_max)|POLYGON (-180.00 -90.00, 180.00 90.00)|2.9.6.1.1.1 & 2.9.6.1.1.2 & 2.9.6.1.1.3 & 2.9.6.1.1.4|westBL (344) & eastBL (345) & southBL (346) & northBL (347)|dcterms:spatial|Bounding box specifying the resources spatial coverage
25|Zeitliche Ausdehnung (Ende)|end_datetime|extras:end_datetime|1|Ende der Gültigkeit eines Datensatzes oder Dienstes.|Element zur zeitlichen Erfassung eines Datensatzes oder Dienstes. Die Angabe des Zeitpunktes erfolgt in folgender Form YYYY-MM-DDThh:mm:ss. TM_Primitive (nach ON EN 8601 bzw. ON EN ISO 19108)|2009-11-23T20:36:00|2.9.6.2.1|exTemp (351)|dcterms:temporal|Date specifying valid to of the resource according to ON EN 8601 or ON EN ISO 19108 respectively.
26|Aktualisierungszyklus|update_frequency|extras:update_frequency|1|Menschenlesbare Frequenz der Aktualisierung des Datensatzes bzw. Dienstes. Codeliste im Anhang c)|Zeitliche Nachführungssequenz für einen Datensatz oder Dienst|monatlich, jährlich|2.9.7.1|maintFreq (143)|dcterms:accrualPeriodicity|Human readable resource update frequency
27|Datenqualität/Herkunft|lineage_quality|extras:lineage_quality|1|Menschenlesbare Beschreibung der Qualitäts- und /oder Entstehungsgenese des Datensatzes oder Dienstes z.B. die Methode der Erhebung.|Allgemeine Angaben zur Qualität und/oder Entstehungsgenese des Datensatzes oder Dienstes|Der Datensatz wurde basierend auf der ÖK50, Stand 2011 digitalisiert. Es wurden alle Waldbestände für die Gemeinde Kopfing erfasst.|3.2.1|statement (83)|dcat:dataQuality|Human readable indication of resource quality and / or data origin, possibly the methodology describing the data collection or acquisition.
28|Titel und Beschreibung Englisch|en_title_and_desc|extras:en_title_and_desc|1|Englische Angabe von Titel und Beschreibung des Datensatzes oder Dienstes.|Titel des Datensatzes oder Dienstes und kurze inhaltliche Beschreibung des Datensatzes bzw. Dienstes für BenutzerInnen in Englisch.|Population of Vienna 2010. Contains the population of permanent residents of Vienna and it’s districts as a moving average in the census period 1st January 2010 to 31st December 2012|2.1.1 & 7.1|resTitle (360) & language|dcterms:abstract (mit language tag "en")|Resource title and description in English
29|Größe des Datensatzes oder Dienstes|resource_size|resources:size|1|Dateigröße.|Die Größe des Datensatzes in Bytes. Die Angabe der Größe ist für Services / Dienste nicht sinnvoll.|899652|-|-|dcat:bytes|Resource size
30|Lizenz Zitat|license_citation|extras:license_citation|1|Die richtige Namensnennung (CC-BY) der Datenquelle laut den Nutzungsbedingungen des jeweiligen Datenportals. Entspricht dem Feld „Datenquelle“ von OGD-Metadaten – 1.1.|Dient dazu, um bei der automatisierten Wiederverwendung von Daten aus einer oder mehreren Datenquellen die richtige Zitierung zu erleichtern.|Datenquelle: CC-BY-3.0: Stadt Linz - data.linz.gv.at|2.8.1.2|accessConsts (70)|cc:attributionName|Attribution as required by CC-BY license
31|Sprache des Datensatzes oder Dienstes|resource_language|resources:language|1|ISO 639-2 dreistelliger ISO Sprachcode für den Datensatz oder Dienst|Sprache, welche der Datensatz oder Dienst verwendet|ger|2.9.3|dataLang (39)|dcterms:language|Resource language
ERROR: BAD RECORD

Шаг 4. Оцените плохие записи.

Как видите, последняя запись не может быть передана. Поэтому вам следует проверить и исправить проблемный текст вручную. Удачи.

person Steve    schedule 18.12.2012
comment
Это уже показывает его потенциал, но не работает в других случаях. У меня очень ограниченные знания awk, но использование RS=ID может быть более надежным? В некоторых случаях я могу отредактировать текстовый файл вручную, если этот формат, автоматически созданный из сохранения PDF, слишком громоздкий. Полный файл находится здесь: gist.github.com/4325714. - person JohnDoe; 18.12.2012
comment
@JohnDoe: Пожалуйста, посмотрите обновление. Если у вас есть какие-либо проблемы, просто спросите. ХТН. - person Steve; 19.12.2012
comment
Это было намного больше, чем я ожидал. Он работает безупречно ... Я добавил «репозиторий:», чтобы обрабатывать его специально для пробелов, и добавить заголовок. Другие оставшиеся сбои связаны с жестокостью, вызванной экспортом PDF в текст и необходимостью работать над этим. Я загрузил все здесь github.com/the42/ogdat/tree/master/ogdatv21 Осталась некоторая оставшаяся работа, и отличия от цели представлены здесь diffnow.com/?report=khc3i Большое спасибо! - person JohnDoe; 19.12.2012

Если это можно сделать, это будет выполнимо в AWK. Фактор, который будет определять это, — насколько предсказуема структура записи.

Например, всегда ли поле Безейхнера будет состоять из двух строк, разделенных пустой строкой? Будет ли он иногда иметь только одну строку?

То же самое для меток левого ряда. Всегда ли они будут одинаковыми? Они отделены от значений табуляцией или пробелами? Всегда ли значения разделяются новой строкой и будут ли значения когда-либо содержать новые строки?

Поможет тот факт, что поля имеют фиксированную ширину. Если вы знаете, сколько строк текста будет в каждом поле, вы можете просто разбить каждую строку на подстроки соответствующей ширины.

Большая проблема с разбором подобных вещей заключается не в техническом решении. Кто-нибудь может написать синтаксический анализатор, который будет правильно анализировать приведенный выше текст, но будет ли он анализировать все экземпляры записей? Опять же, это зависит от того, насколько жестким является формат записи и насколько варьируется ее структура.

Да, AWK может это сделать, если это можно сделать.

person Foo    schedule 17.12.2012