
Apreciaría tu ayuda. Estoy extrayendo información de archivos de datos que en algunos casos tienen un tamaño de más de un terabyte.
- Las variables en cada línea están separadas por espacios en blanco.
- La cantidad de variables en cada línea es fija para cada archivo.
- Tres columnas a la derecha siempre números naturales.
- Las líneas siempre comienzan con una matriz.
- Las matrices siempre contienen una cantidad fija de elementos por archivo
- Las matrices pueden contener de 1 a 5 elementos.
- El archivo de datos de origen está ordenado correctamente
El siguiente ejemplo compara una matriz de tres elementos con cualquier otra matriz en el archivo o fragmento cuando se usa paralelo. Si la matriz coincide, se agrega la segunda columna desde la derecha y las líneas se fusionan. La columna más a la derecha y la columna -2 están vacías.
g@grml # zcat googlebooks-eng-us-all-3gram-20120701-zz.gz | head
Z'Z . _END_ 1840 1 1
Z'Z . _END_ 1847 1 1
Z'Z . _END_ 1850 1 1
Z'Z . _END_ 1855 1 1
Z'Z . _END_ 1856 1 1
Z'Z . _END_ 1857 1 1
Z'Z . _END_ 1860 1 1
Z'Z . _END_ 1863 1 1
Z'Z . _END_ 1865 1 1
Z'Z . _END_ 1869 1 1
g@grml # zcat googlebooks-eng-us-all-3gram-20120701-zz.gz | parallel -k -q --pipe awk '{a[$1" "$2" "$3] +=$(NF-1)} END{for (i in a) print i, a[i]}' | head
Zz_NOUN _NOUN_ , 98
zz _._ _PRT_ 120
ZZ or_CONJ _NOUN_ 122
ZZ_NOUN _DET_ _VERB_ 59
zz_DET _NOUN_ . 86
ZZ is_VERB reached 42
ZZ_NUM ^ ^ 65
ZZ _NOUN_ _VERB_ 3163
ZZ ,_. " 52
ZZ / _NUM_ 275
Aunque el ejemplo muestra una matriz de 3 elementos, estoy trabajando con matrices que contienen de 1 a 5 elementos.
awk '{a[$1] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2" "$3] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2" "$3" "$4] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2" "$3" "$3" "$5] +=$(NF-1)} END{for (i in a) print i, a[i]}'
¿Cómo le digo a awk que compare la matriz actual con la matriz anterior en la línea anterior en lugar de que awk intente hacer coincidir cada matriz con cada matriz en un archivo o fragmento?
Gracias
Archivo fuente de ejemplo.
wget --show-progress -cq http://storage.googleapis.com/books/ngrams/books/googlebooks-eng-us-all-3gram-20120701-zz.gz -O - | zcat
Respuesta1
Los datos de entrada proporcionados como URL en un comentario están delimitados por tabulaciones. Esto significa que podemos analizar su primer campo delimitado por tabulaciones como una especie de "clave" para comparar con otras líneas. Hacemosnodebe preocuparse por las palabras separadas por espacios dentro del primer campo, pero puede tratar todo el primer campo como una sola entidad.
BEGIN { OFS = FS = "\t" }
{
count = $(NF - 1)
key = $1
}
key != previous {
if (previous != "")
print previous, sum
sum = 0
}
{
sum += count
previous = key
}
END {
if (previous != "")
print previous, sum
}
Este awk
programa analiza el campo "recuento" (penúltimo campo) y count
luego utiliza el primer campo como "clave" para compararlo posteriormente con la clave de la línea anterior. Este es el primer bloque después del BEGIN
bloque (que simplemente establece delimitadores de entrada y salida).
Si la clave es diferente de la clave de la línea anterior, esto significa que ahora estamos viendo otro conjunto de palabras. Genere la clave y la suma de la línea anterior y restablezca la suma.
Para todas las líneas, incremente la suma por el recuento de esta línea y actualice previous
(ahora hemos terminado con esta línea, por lo que esta línea key
es la siguiente previous
).
Al final, genere la información de la última línea de los datos.
Ejecutarías esto usando awk -f script.awk inputfile
.
Como "una sola línea":
awk -F '\t' 'BEGIN{OFS=FS} {c=$(NF-1);k=$1} k!=p {if(p!="")print p,s;s=0} {s+=c;p=k} END {if(p!="") print p,s}' file