使用 awk 和 gsub 根據另一列修改特定列

使用 awk 和 gsub 根據另一列修改特定列

我有一個包含數百萬行和列的文件(file1)。數據示例如下:

"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

我想找到 col1 中具有 AAA 的所有行,然後取得 col5 中具有 BGB 的所有行。最後,將 col2、col3、col4 和 col6 中的每個值減少 50%(如果單元格值為 0 或空白則忽略)。並列印文件的所有行。所以,我的輸出將如下所示:

"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

我一直在嘗試以下操作,但無法使其工作(而且,無法弄清楚如何在 gsub 中使用多個列)

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

答案1

awk 可以像 grep 一樣匹配模式,因此管道中幾乎不需要 grep 和 awk。

你可以做

 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

或者,如果你想讓列減少更多的動態

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

相關內容