
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