
Necesito ayuda con el script de shell, tengo 2 archivos grandes de alrededor de 1,2 GB de datos, con claves y valores, necesito comparar ambos archivos según la clave y almacenar la diferencia en el valor en el tercer archivo y el único en el archivo 1.
archivo 1:
test1 marco;polo;angus
test2 mike;zen;liza
test3 tom;harry;alan
test4 bob;june;janet
archivo 2:
test1 polo;angus
test2 mike
test4 bob;janet
Me gustaría comparar las dos primeras columnas del archivo1 con el archivo2 (buscar en todo el contenido del archivo2 en las dos primeras columnas) si coinciden, imprima la diferencia de valores. Luego busque la segunda línea del archivo 1 y así sucesivamente. También se deben imprimir las claves únicas en el archivo 1.
Rendimiento esperado:
test1 marco
test2 zen;liza
test3 tom;harry;alan
test4 june
Los archivos que tengo son enormes y contienen alrededor de 100.000 líneas, por lo que me gustaría agilizar la ejecución. Esto se ejecuta en un script de shell, usando #!/usr/bin/env bash.
, por ejemplo:
1332239_44557576_CONTI Lased & Micro kjd $353.50_30062020_lsdf3_no-rule 343323H;343434311H;454656556H;343343432H
Es un archivo de texto simple, con esto como clave ( 1332239_44557576_CONTI Lased & Micro kjd $353.50_30062020_lsdf3_no-rule
) y estos como valores: ( 343323H;343434311H;454656556H;343343432H
)
El archivo 2 siempre será un subconjunto del archivo 1, solo necesita encontrar valores (contra la clave) que no están presentes en el archivo 2 y únicos en el Archivo 1.
Respuesta1
Usando script en perl:
Se supone que estás buscandoarchivo2 basado en archivo1y no al revés. Si también desea buscar el archivo 1 basándose en el archivo 2, debeagregar otro bucle forpara el diccionario file2 (hash).
Archivos de información:
$ cat file1.txt
test1 marco;polo;angus
test2 mike;zen;liza
test3 tom;harry;alan
test4 bob;june;janet
$ cat file2.txt
test1 polo;angus
test2 mike
test4 bob;janet
Guion :
#!/usr/bin/perl
use warnings;
use strict;
my $file1=$ARGV[0];
my $file2=$ARGV[1];
my %dict1; #Stores file1 unique key and value pairs in this dictionary ( HASH in perl )
my %dict2; #Stores file2 unique key and value pairs in this dictionary ( HASH in perl )
my %output; #This is output dictionary after processing all the data to print it out
open(F1,'<',$file1) or die "File not found $file1";
open(F2,'<',$file2) or die "File not found $file2";
#Store both file's contents in %dict1 and %dict2 respectively
while(<F1>)
{
my ($key,$value) = split(/\s+/,$_);
$dict1{$key} = $value;
}
while(<F2>)
{
my ($key,$value) = split(/\s+/,$_);
$dict2{$key} = $value;
}
#Get the unique(difference) value from file2 based in the values in file1
foreach my $k ( keys %dict1 )
{
if ( defined $dict2{$k} )
{
my @dict1values=split(";",$dict1{$k});
my @dict2values=split(";",$dict2{$k});
foreach (@dict1values)
{
if ( $dict2{$k} !~ /[;]*?$_[;]*?/) {
$output{$k} .=$_.";";
}
}
} else {
$output{$k}=$dict1{$k};
}
}
foreach my $ke (sort(keys(%output)))
{
print "$ke $output{$ke}\n" if ( defined($output{$ke}) );
}
Producción :
$ ./testing.pl file1.txt file2.txt
test1 marco;
test2 zen;liza;
test3 tom;harry;alan
test4 june;
Respuesta2
Aquí hay unawkversión que debería ser muy rápida.
Funciona en cualquier cosa que siga el patrón de campo solicitado [cadena:clave][espacio|";"][cadena][espacio|";"] etc.
$ cat file1;echo "";cat file2
test1 marco;polo;angus
test2 mike;zen;liza
test3 tom;harry;alan
test4 bob;june;janet
test1 polo;angus
test2 mike
test4 bob;janet
$ awk -F '[ ;]' '
NR==FNR{ for(i=2;i<=NF;i++){ k[$1,$i]++ } }
NR!=FNR{ for(i=2;i<=NF;i++){ k[$1,$i]++ } }
END{ for(i in k){
if(k[i]==1){
split(i,arr_i,SUBSEP);
k_e[arr_i[1]]=k_e[arr_i[1]]""arr_i[2]";"
}
}
for(i in k_e){
print i" "k_e[i]
}
}' file1 file2 | sort | sed 's/.$//'
test1 marco
test2 liza;zen
test3 harry;alan;tom
test4 june