
Disculpas de antemano porque estoy seguro de que este es un problema fácil. Sin embargo, ahí va.
cat blah.txt
aa+2
bb+4
cc+10
dd+31
Me gustaría procesar blah.txt para producir lo siguiente:
aa+0
bb+2
cc+6
dd+16
La idea aquí es que la primera columna podría ser una lista de canciones y la segunda, sus horas de inicio.
Mi corazonada fue hacer esto usando awk. Pensé en dos matrices con índices numéricos que almacenan $1 y el total acumulado de $2. Mi idea era cambiar el índice numérico de los totales acumulados en 1.
tail -r blah.txt |
awk -F "+" '{ for(i=0;i<=NR;i++) arr[i+1]+=$2; farr[i]=$1 } END
{ for(i=NR+1;i>1;i--) {if (i==NR) {print farr[NR] FS 0 }
else { print farr[i] FS arr[i]}}}'
Esto no es conciso y, además, no funciona. Estoy desconcertado por el fracaso de la creación de la matriz, sobre todo.
De todos modos, dijo 'nuf, ¿podría alguna persona amable sacarme de mi miseria?
Tomás
Respuesta1
Aquí tienes:
$ awk -F+ '{sum+=$2;printf("%s+%d\n",$1,sum-$2);}' blah.txt
aa+0
bb+2
cc+6
dd+16
Edit1: aquí hay una forma un poco más sencilla, gracias a Sukminder
$ awk -F+ '{printf("%s+%d\n",$1,sum);sum+=$2}' blah.txt
Edit2: Y un poco más conciso, gracias a Bernhard:
$ awk -F+ '{print $1,sum;sum+=$2}' OFS="+" blah.txt
Edit3: pero el primero no muestra 0 en la primera línea, por lo que aquí hay una versión corregida y algo completa que muestra la forma más corta de responder la pregunta de Tom (hasta que algún comentario nuevo sugiera uno mejor):
$ awk -F+ '{print$1,s+0;s+=$2}' OFS=+ blah.txt
Respuesta2
La mejor manera de hacerlo es aprender y usar expresiones regulares, porque en el futuro te ahorrará muchos problemas haciendo ese tipo de cosas.
cat blah.txt | gawk 'match($0, /([^0-9]*)([0-9]+)/, ary) {print ary[1] ary[2]-2}'
Tendrás que sustituir los últimos 2 por tu variable de turno. Debes tener en cuenta el uso de gawk
. Hasta donde yo sé, regular awk
no puede extraer grupos de expresiones regulares.
¿Qué hace esto? Hace una coincidencia $0
, colocando los resultados en ary
, usando una expresión regular /([^0-9]*)([0-9]+)/
, que coincide con: ([^0-9]*)
- 0 o más caracteres que no son números y los coloca en el primer índice de la matriz (los paréntesis son responsables de eso llamado agrupación), luego ([0-9]+)
coincide con un número de longitud distinta de cero (y lo pone como segundo elemento de la matriz).
Por supuesto, esto se puede hacer más elaborado, junto con algunas comprobaciones de errores, casos especiales de coincidencia, etc., pero le animo a que explore esto (es decir, las expresiones regulares) por su cuenta.