Tengo este archivo de texto sin formato que necesito examinar automáticamente y escribir los resultados en otro archivo de texto sin formato. Tenga en cuenta que usaré texto sin formato y CSV indistintamente, ya que los CSV son texto sin formato con un separador común entre datos (comas, tabulaciones, etc.).
Ejemplos de datos
ABD-01A
ABD-01B
ABD-01C
AL-25A
AL-25B
Proceso uno- reconocer las dos primeras secciones de los datos ( text
- number
) para repetirlas y contarlas en el CSV de salida:
ABD-01,1
ABD-01,2
ABD-01,3
AL-25,1
AL-25,2
Proceso dos- La primera parte de los datos recopilados anteriormente tiene una especie de clave principal asignada en un archivo diferente. También me gustaría obtener las claves principales mencionadas en los archivos recién generados:
#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
Básicamente, lo que le pregunto es si hay algún software que pueda ayudarme con esto en sistemas operativos basados en Windows o Linux. Bash puede ayudarme con un procesamiento más sencillo, pero no creo que pueda manejar tanto. Por favor avise.
Respuesta1
- Elija su idioma preferido: Perl funciona bien con texto; Python, PHP y Ruby están bien, aunque un poco más lentos.
- Lea primero el archivo clave:
- dividir cada
key,data
línea enkey
ydata
, - luego almacene ambos en un dict/hash/array:
keys[data] = key
- también
counts[data] = 0
si el lenguaje exige inicialización
- dividir cada
- Leer todos los archivos de datos:
- use una expresión regular para encontrar los datos "NÚMERO DE TEXTO" al principio de cada línea,
- incrementar
counts[data]
en uno, - e inmediatamente genera
keys[data]
, la línea ycounts[data]
.
Escribí un script de ejemplo tanto en Perl como en Python, así que tu elección:
proceso.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);
}
proceso.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)
Respuesta2
lo haría enPitónusandoexpresiones regulares. Simplemente escriba python
su shell para ver si está instalado.
De lo contrario puedes usarperla. Simplemente escriba perl
su shell para ver si está instalado. Es decir tienesoporte incorporado de expresiones regulares.
Respuesta3
Proceso 1
perl count.pl datafile …
donde count.pl es algo así como
#!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";
}
}
No probado, advertencia emptor.
Proceso 2
Agrega algo como
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;
}
y cambie la línea de impresión END {}
a
print "$key{$_},$_,$headwordcount{$_}\n";
De nuevo, sin probar.
Generará advertencias si el archivo de datos contiene encabezados que no están en el archivo clave. Puede verificar si $key{$_}
no está definido y, de ser así, imprimir sin clave.