AWK:满足模式时在列中编辑值

时间:2015-11-19 20:50:39

标签: awk

我有一个标签分隔的csv文件,有3500行。在此文件中,我必须编辑第5列和第6列中的值,具体取决于第3,4和5列的值。

规则:

我们只需编辑第5列中的值不超过" 3500"

的行。

正如您所看到的,第6列中的值是第5列和第7列的concanetacion。

如果第3列和第4列中的值为:

"AR" "ES" => add 10000 to the value in column 5.
"BE" "FR" => add 20000 to the value in column 5.
"BE" "NL" => add 30000 to the value in column 5.
"BR" "PT" => add 40000 to the value in column 5.
"DK" "DA" => add 50000 to the value in column 5.

该文件包含

voc_sales_ren   "QSA"   "AR"    "ES"    "100"   "100reto"   "reto"
voc_sales_ren   "QSA"   "AR"    "ES"    "11"    "11reto"    "reto"
voc_sales_ren   "QSA"   "AR"    "ES"    "9654236"   "9654236expe"   "expe"
voc_sales_ren   "QSA"   "BE"    "FR"    "1078"  "1078reto"  "reto"
voc_sales_ren   "QSA"   "BE"    "NL"    "027460652" "027460652expe" "expe"
voc_sales_ren   "QSA"   "BE"    "NL"    "027460652" "027460652reto" "reto"
voc_sales_ren   "QSA"   "BR"    "PT"    "1045"  "1045reto"  "reto"
voc_sales_ren   "QSA"   "BR"    "PT"    "1046"  "1046reto"  "reto"
voc_sales_ren   "QSA"   "BR"    "PT"    "1094"  "1094reto"  "reto"
voc_sales_ren   "QSA"   "DK"    "DA"    "017187074" "017187074reto" "reto"
voc_sales_ren   "QSA"   "DK"    "DA"    "017187090" "017187090reto" "reto"
voc_sales_ren   "QVN"   "DK"    "DA"    "384"   "384reto"   "reto"
voc_sales_ren   "QVN"   "DK"    "DA"    "387"   "387reto"   "reto"
voc_sales_ren   "QVN"   "BE"    "NL"    "1019"  "1019reto"  "reto"

预期产出:

voc_sales_ren   "QSA"   "AR"    "ES"    "10100" "10100reto" "reto"
voc_sales_ren   "QSA"   "AR"    "ES"    "10011" "10011reto" "reto"
voc_sales_ren   "QSA"   "AR"    "ES"    "9654236"   "9654236expe"   "expe"
voc_sales_ren   "QSA"   "BE"    "FR"    "21078" "21078reto" "reto"
voc_sales_ren   "QSA"   "BE"    "NL"    "027460652" "027460652expe" "expe"
voc_sales_ren   "QSA"   "BE"    "NL"    "027460652" "027460652reto" "reto"
voc_sales_ren   "QSA"   "BR"    "PT"    "41045" "41045reto" "reto"
voc_sales_ren   "QSA"   "BR"    "PT"    "41046" "41046reto" "reto"
voc_sales_ren   "QSA"   "BR"    "PT"    "41094" "41094reto" "reto"
voc_sales_ren   "QSA"   "DK"    "DA"    "017187074" "017187074reto" "reto"
voc_sales_ren   "QSA"   "DK"    "DA"    "017187090" "017187090reto" "reto"
voc_sales_ren   "QVN"   "DK"    "DA"    "50384" "50384reto" "reto"
voc_sales_ren   "QVN"   "DK"    "DA"    "50387" "50387reto" "reto"
voc_sales_ren   "QVN"   "BE"    "NL"    "301019"    "301019reto"    "reto"

2 个答案:

答案 0 :(得分:1)

试一试......

#!/usr/bin/awk -f

BEGIN {
        to_add["\"AR\"" "\"ES\""] = 10000
        to_add["\"BE\"" "\"FR\""] = 20000
        to_add["\"BE\"" "\"NL\""] = 30000
        to_add["\"BR\"" "\"PT\""] = 40000
        to_add["\"DK\"" "\"DA\""] = 50000
        OFS = "   "
    }

    {
        split($5, num, "\"")
    }

num[2] > 3500   {
        print
    }

num[2] <= 3500 {
        split($7, cat, "\"")
        $5 = num[2] + to_add[$3 $4]
        $6 = "\"" $5 cat[2] "\""
        $5 = "\"" $5 "\""
        $5 = $5
        print
    }

我不确定文件中的间距是否必不可少,所以我没有特别尝试保留它,只是将所有内容设置为3个空格。输出是:

voc_sales_ren   "QSA"   "AR"   "ES"   "10100"   "10100reto"   "reto"
voc_sales_ren   "QSA"   "AR"   "ES"   "10011"   "10011reto"   "reto"
voc_sales_ren   "QSA"   "AR"    "ES"    "9654236"   "9654236expe"   "expe"
voc_sales_ren   "QSA"   "BE"   "FR"   "21078"   "21078reto"   "reto"
voc_sales_ren   "QSA"   "BE"    "NL"    "027460652" "027460652expe" "expe"
voc_sales_ren   "QSA"   "BE"    "NL"    "027460652" "027460652reto" "reto"
voc_sales_ren   "QSA"   "BR"   "PT"   "41045"   "41045reto"   "reto"
voc_sales_ren   "QSA"   "BR"   "PT"   "41046"   "41046reto"   "reto"
voc_sales_ren   "QSA"   "BR"   "PT"   "41094"   "41094reto"   "reto"
voc_sales_ren   "QSA"   "DK"    "DA"    "017187074" "017187074reto" "reto"
voc_sales_ren   "QSA"   "DK"    "DA"    "017187090" "017187090reto" "reto"
voc_sales_ren   "QVN"   "DK"   "DA"   "50384"   "50384reto"   "reto"
voc_sales_ren   "QVN"   "DK"   "DA"   "50387"   "50387reto"   "reto"
voc_sales_ren   "QVN"   "BE"   "NL"   "31019"   "31019reto"   "reto"

这是交易:

  1. 首先,它设置要在BEGIN子句中添加的值。它们位于稍后将引用的数组中。
  2. 它在双引号字符上拆分字段5。这是剥离报价的便宜而简单的方法。
  3. 如果字段5的数值小于或等于3500,则执行所需的更改。要做到这一点,它(a)从7美元中剥离报价,(b)将BEGIN中设置的价值加上5美元,相当于3美元和4美元,(c)预先加上双引号和5美元的新价值7美元的字母部分,(d)将新的报价放在5美元的新价值上,并且(e)重建线条和印刷品。
  4. 如果大于3500,只需打印该行。

答案 1 :(得分:0)

以这种方式举报?

包含这些代码的文件名awk_script

#!/usr/bin/awk
#store all codes in an array
BEGIN{ar["ARES"]=10000;ar["BEFR"]=20000;ar["BENL"]=30000;ar["BRPT"]=40000;ar["DKDA"]=50000} 
{gsub(/["]/,"",$0) # take out all quotes, we will put them back
if(($3 $4 in ar)){   #test to see if column 3 and 4 match your array codes
    $5=$5+ar[$3$4];
    gsub(/^[0-9]+/,$5,$6); 
 };
for(i=2;i<=NF;++i){  #add back you quotes
    $i=qt $i qt};print
}

一样运行脚本
awk -v qt='"' -f awk_script

您的预期输出

voc_sales_ren "QSA" "AR" "ES" "10100" "10100reto" "reto"
voc_sales_ren "QSA" "AR" "ES" "10011" "10011reto" "reto"
voc_sales_ren "QSA" "AR" "ES" "9664236" "9664236expe" "expe"
voc_sales_ren "QSA" "BE" "FR" "21078" "21078reto" "reto"
voc_sales_ren "QSA" "BE" "NL" "27490652" "27490652expe" "expe"
voc_sales_ren "QSA" "BE" "NL" "27490652" "27490652reto" "reto"
voc_sales_ren "QSA" "BR" "PT" "41045" "41045reto" "reto"
voc_sales_ren "QSA" "BR" "PT" "41046" "41046reto" "reto"
voc_sales_ren "QSA" "BR" "PT" "41094" "41094reto" "reto"
voc_sales_ren "QSA" "DK" "DA" "17237074" "17237074reto" "reto"
voc_sales_ren "QSA" "DK" "DA" "17237090" "17237090reto" "reto"
voc_sales_ren "QVN" "DK" "DA" "50384" "50384reto" "reto"
voc_sales_ren "QVN" "DK" "DA" "50387" "50387reto" "reto"
voc_sales_ren "QVN" "BE" "NL" "31019" "31019reto" "reto"