Ändern Sie bestimmte Spalten basierend auf einer anderen Spalte mithilfe von awk und gsub

Ändern Sie bestimmte Spalten basierend auf einer anderen Spalte mithilfe von awk und gsub

Ich habe eine Datei (file1) mit Millionen von Zeilen und Spalten. Ein Beispiel für Daten sind:

"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

Ich möchte alle Zeilen finden, die AAA in Spalte 1 haben, und dann alle Zeilen abrufen, die BGB in Spalte 5 haben. Und schließlich jeden Wert in Spalte 2, Spalte 3, Spalte 4 und Spalte 6 um 50 % verringern (Ignorieren, wenn die Zellenwerte 0 oder leer sind). Und alle Zeilen der Datei drucken. Meine Ausgabe sieht also folgendermaßen aus:

"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

Ich habe Folgendes versucht, aber es hat nicht funktioniert (und ich konnte auch nicht herausfinden, wie man mehrere Spalten in gsub verwendet).

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

Antwort1

awk kann Muster wie grep abgleichen, daher benötigen Sie grep und awk in einer Pipeline fast nie.

Du könntest es tun

 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

Oder, wenn Sie die Spalten dynamischer gestalten möchten

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

verwandte Informationen