Eu tenho esse arquivo de texto simples que preciso ser examinado automaticamente e os resultados escritos em outro arquivo de texto simples. Observe que usarei texto simples e CSV de forma intercambiável, pois CSVs são texto simples com separador comum entre dados (vírgulas, tabulações, etc.).
Exemplos de dados
ABD-01A
ABD-01B
ABD-01C
AL-25A
AL-25B
Processe um- reconhecer as duas primeiras seções dos dados ( text
- number
) para repeti-las e contá-las no CSV de saída:
ABD-01,1
ABD-01,2
ABD-01,3
AL-25,1
AL-25,2
Processo dois- A primeira parte dos dados coletados acima possui uma espécie de chave primária atribuída a eles em um arquivo diferente. Gostaria de obter também as chaves primárias mencionadas nos arquivos recém-gerados:
#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
Então, basicamente, o que estou perguntando a ela é se existe algum software que possa me ajudar com isso em sistemas operacionais baseados em Windows ou Linux. O Bash pode me ajudar com um processamento mais simples, mas não acho que possa lidar com tanta coisa. Por favor, avise.
Responder1
- Escolha seu idioma preferido – Perl funciona bem com texto; Python, PHP e Ruby estão bem, embora um pouco mais lentos.
- Leia o arquivo-chave primeiro:
- divida cada
key,data
linha emkey
edata
, - em seguida, armazene ambos em um dict/hash/array:
keys[data] = key
- também
counts[data] = 0
se a linguagem exigir inicialização
- divida cada
- Leia todos os arquivos de dados:
- use um regexp para encontrar os dados "TEXT-NUMBER" no início de cada linha,
- incrementar
counts[data]
em um, - e imediatamente produza
keys[data]
, a linha ecounts[data]
.
Eu escrevi um script de exemplo em Perl e Python, então sua escolha:
processo.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);
}
processo.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)
Responder2
eu faria isso emPitãousandoexpressões regulares. Basta digitar python
seu shell para ver se ele está instalado.
Caso contrário, você pode usarPerl. Basta digitar perl
seu shell para ver se ele está instalado. É temsuporte integrado para expressões regulares.
Responder3
Processo 1
perl count.pl datafile …
onde count.pl é algo 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";
}
}
Não testado, caveat emptor.
Processo 2
Adicione 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;
}
e altere a linha de impressão END {}
para
print "$key{$_},$_,$headwordcount{$_}\n";
Novamente, não testado.
Você gerará avisos se o arquivo de dados contiver palavras-chave que não estejam no arquivo-chave. Você pode verificar se $key{$_}
está indefinido e, em caso afirmativo, imprimir sem chave.