Verarbeiten von Klartextdaten

Verarbeiten von Klartextdaten

Ich habe diese reine Textdatei, die ich automatisch untersuchen lassen muss, und die Ergebnisse müssen in eine andere reine Textdatei geschrieben werden. Beachten Sie, dass ich reine Textdatei und CSV synonym verwende, da CSVs reine Textdatei mit einem gemeinsamen Trennzeichen zwischen den Daten sind (Kommas, Tabulatoren usw.).

Datenbeispiele

ABD-01A
ABD-01B
ABD-01C
AL-25A
AL-25B

Prozess eins- Erkennen Sie die ersten beiden Abschnitte der Daten ( text- number), um sie in der CSV-Ausgabe zu wiederholen und zu zählen:

ABD-01,1
ABD-01,2
ABD-01,3
AL-25,1
AL-25,2

Prozess zwei- Dem ersten Teil der oben gesammelten Daten ist eine Art Primärschlüssel in einer anderen Datei zugewiesen. Ich möchte die in den neu generierten Dateien erwähnten Primärschlüssel ebenfalls erhalten:

#primary key file
1,ABD-01
2,ABD-02
3,AL-02
20,AL-25

#newly generated file
1,ABD-01,1
1,ABD-01,2
1,ABD-01,3
20,AL-25,1
20,AL-25,2

Ich frage sie also im Grunde, ob es Software gibt, die mir dabei unter Windows- oder Linux-basierten Betriebssystemen helfen kann. Bash kann mir bei einfacheren Verarbeitungen helfen, aber ich glaube nicht, dass es so viel bewältigen kann. Bitte geben Sie mir einen Rat.

Antwort1

  1. Wählen Sie Ihre bevorzugte Sprache – Perl funktioniert gut mit Text; Python, PHP und Ruby sind okay, wenn auch etwas langsamer.
  2. Lesen Sie zuerst die Schlüsseldatei:
    • teilen Sie jede key,dataZeile in keyund auf data,
    • dann speichern Sie beides in einem Dict/Hash/Array:keys[data] = key
    • auch counts[data] = 0wenn die Sprache eine Initialisierung erfordert
  3. Alle Datendateien lesen:
    1. Verwenden Sie einen regulären Ausdruck, um die „TEXT-NUMBER“-Daten am Anfang jeder Zeile zu finden.
    2. counts[data]um eins erhöhen ,
    3. und geben Sie sofort keys[data]die Zeile und aus counts[data].

Ich habe ein Beispielskript sowohl in Perl als auch in Python geschrieben, Sie haben also die Wahl:

prozess.pl

#!/usr/bin/env perl
use strict;

sub usage {
    print "Usage: $0 <key_file> <data_file...>\n";
    return 2;
}

my $keys_file = shift(@ARGV) // exit(usage);
my @data_files = @ARGV;

my %keys;   # $data => $primarykey
my %counts; # $data => $count

# Read keys

open(my $fh, "<", $keys_file) or die "$!";
while (my $line = <$fh>) {
    chomp($line);
    my ($key, $datum) = split(/,/, $line, 2);
    if (!defined $datum) {
        warn "$keys_file: line $. not in KEY,DATA format: '$line'\n";
        next;
    }

    $keys{$datum} = $key;
    $counts{$datum} = 0;
}
close($fh);

# Read and output data

my $ex = qr/^(\w+-\d+)\w*/;
for my $data_file (@data_files) {
    open(my $fh, "<", $data_file) or die "$!";
    while (my $line = <$fh>) {
        chomp($line);
        if ($line =~ /$ex/) {
            my $datum = $1;
            if (!defined $keys{$datum}) {
                warn "no primary key found for data '$datum'\n";
                next;
            }

            # Increment count, then print processed line immediately
            $counts{$datum}++;
            print "$keys{$datum},$&,$counts{$datum}\n";
        }
        else {
            warn "$data_file: line $. does not begin with TEXT-NUMBER: '$_'\n";
        }
    }
    close($fh);
}

prozess.py

#!/usr/bin/env python
from __future__ import print_function
import sys
import re

def usage():
    print("Usage: %s <key_file> <data_file...>" % sys.argv[0])
    return 2

try:
    keys_file = sys.argv[1]
    data_files = sys.argv[2:]
except IndexError:
    sys.exit(usage())
except ValueError:
    sys.exit(usage())

keys = {}
counts = {}

# Read keys

for line in open(keys_file, "r"):
    try:
        key, datum = line.strip().split(",", 1)
    except ValueError:
        print("%s: line not in KEY,DATA format: %r" \
            % (keys_file, line.strip()), file=sys.stderr)
        continue

    keys[datum] = key
    counts[datum] = 0

# Read and output data

ex = re.compile(r'^(\w+-\d+)\w*')
for data_file in data_files:
    for line in open(data_file, "r"):
        line = line.strip()
        m = re.match(ex, line)
        if m:
            datum = m.group(1)
            if datum not in keys:
                print("no primary key found for data %r" % datum,
                    file=sys.stderr)
                continue

            # Increment count, then print processed line immediately
            counts[datum] += 1
            print("%s,%s,%d" % (keys[datum], m.group(0), counts[datum]))
        else:
            print("%s: line does not begin with TEXT-NUMBER: %r" \
                % (data_file, line.strip()), file=sys.stderr)

Antwort2

Ich würde es tun inPythonmitReguläre Ausdrücke. Geben Sie es einfach pythonin Ihre Shell ein, um zu sehen, ob es installiert ist.

Andernfalls können SiePerl. Geben Sie einfach perlIhre Shell ein, um zu sehen, ob es installiert ist. Istintegrierte Unterstützung für reguläre Ausdrücke.

Antwort3

Prozess 1

perl count.pl datafile …

wobei count.pl so etwas ist wie

#!perl
use strict;
use warnings;

my %headwordcount;

while (<>) {
  if (/^([A-Z]+-\d+)/) { $headwordcount{$1}++; }
  # else { warn "Bad data: $_"; } # uncomment line for data warnings
}

END {
  foreach (sort keys %headwordcount) {
     print "$_,$headwordcount{$_}\n";
  }
}

Ungetestet, Vorsicht beim Kauf.

Prozess 2

Fügen Sie etwas hinzu wie

   my %key;

   BEGIN {
     my $keyfilename = 'primary.key';
     open my $fh, '<', $keyfilename or die "Can't read '$keyfilename' - $!\n";
     while (<$fh>) {
        chomp;
        my ($key,$headword) = split(/,/, $_, 2);
        $key{$headword} = $key;        
     }
     close $fh;
   }

und ändern Sie die Druckzeile END {}in

   print "$key{$_},$_,$headwordcount{$_}\n";

Wiederum ungetestet.

Sie generieren Warnungen, wenn die Datendatei Stichwörter enthält, die nicht in der Schlüsseldatei enthalten sind. Sie können prüfen, ob $key{$_}sie undefiniert sind, und ggf. ohne Schlüssel drucken.

verwandte Informationen