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
- Wählen Sie Ihre bevorzugte Sprache – Perl funktioniert gut mit Text; Python, PHP und Ruby sind okay, wenn auch etwas langsamer.
- Lesen Sie zuerst die Schlüsseldatei:
- teilen Sie jede
key,data
Zeile inkey
und aufdata
, - dann speichern Sie beides in einem Dict/Hash/Array:
keys[data] = key
- auch
counts[data] = 0
wenn die Sprache eine Initialisierung erfordert
- teilen Sie jede
- Alle Datendateien lesen:
- Verwenden Sie einen regulären Ausdruck, um die „TEXT-NUMBER“-Daten am Anfang jeder Zeile zu finden.
counts[data]
um eins erhöhen ,- und geben Sie sofort
keys[data]
die Zeile und auscounts[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 python
in Ihre Shell ein, um zu sehen, ob es installiert ist.
Andernfalls können SiePerl. Geben Sie einfach perl
Ihre 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.