modificar columnas específicas basadas en otra columna usando awk y gsub

modificar columnas específicas basadas en otra columna usando awk y gsub

Tengo un archivo (archivo1) con millones de filas y columnas. Un ejemplo de datos son:

"col1","col2","col3","col4","col5","col6"
"AAA",0,5,10,"BGB",50
"BBB",4,7,10,"BFD",76
"AAA",15,0,0,"BGB",20
"AAA",10,13,10,"DDD",23

Quiero encontrar todas las líneas que tienen AAA en col1 y luego obtener todas las filas que tienen BGB en col5. Y finalmente, disminuya el 50% de cada valor en col2, col3, col4 y col6 (ignore si los valores de celda son 0 o están en blanco). E imprima todas las líneas del archivo. Entonces, mi salida se verá así:

"col1","col2","col3","col4","col5","col6"
"AAA",0,2.5,5,"BGB",25
"BBB",4,7,10,"BFD",76
"AAA",7.5,0,0,"BGB",10
"AAA",10,13,10,"DDD",23

He estado intentando lo siguiente, pero no pude hacerlo funcionar (además, no pude descubrir cómo usar varias columnas en gsub)

grep AAA file1 | awk -F "," '$5~/BGB/ {gsub($6,\substr($6,1,length($6)-1)*0.50\, $6}1'

Respuesta1

awk puede coincidir con patrones como lo hace grep, por lo que casi nunca necesitas grep y awk en una canalización.

Podrías hacerlo

 awk  '
    BEGIN {FS = OFS = ","}
    $1 ~ /AAA/ && $5 ~ /BGB/ {
        if ($2) $2 = $2 / 2
        if ($3) $3 = $3 / 2
        if ($4) $4 = $4 / 2
        if ($6) $6 = $6 / 2
    }
    1
' file

O, si desea que las columnas para reducir sean más dinámicas

awk -v "columns=2,3,4,6" '
    BEGIN {
        FS = OFS = ","
        n = split(columns, a, /,/)
        for (i=1; i<=n; i++) cols[a[i]]=1
    }
    $1 ~ /AAA/ && $5 ~ /BGB/ {
        for (c in cols) if ($c) $c = $c / 2
    }
    1
' file

información relacionada