【问题标题】:awk filter columns with calculated values and number range | updated具有计算值和数字范围的 awk 过滤列 |更新
【发布时间】:2020-10-30 22:43:24
【问题描述】:

您好,我不知道如何实现给定的预期输出 输入文件,当前代码给出输出,但需要预期一个

input file                     awk code output
--------

3700 TEXT_0A 34 NA NA        | 3700  TEXT_0A  34    NA   NA    850
3721 TEXT_0A 55 ete 851      | 3721  TEXT_0A  55    ete  851   850
3701 TEXT_0A 100 NA NA       | 3701  TEXT_0A  100   NA   NA    850
3724 TEXT_0A 150 ete 1275    | 3724  TEXT_0A  150   ete  1275  1275
3713 TEXT_0A 170 ete 1445    | 3713  TEXT_0A  170   ete  1445  1445
25 TEXT_XA 200 ete 822       | 3686  TEXT_0A  200   ete  822   1700
3686 TEXT_0A 200 ete 822     | 3692  TEXT_0A  200   ete  1700  1700
3692 TEXT_0A 200 ete 1700    | 3716  TEXT_0A  200   ete  3000  1700
3716 TEXT_0A 200 ete 3000    | 3688  TEXT_0A  250   ete  822   1875
88 TEXT_AF 250 ete 822       | 3708  TEXT_0A  300   ete  2250  2250
69 DNTT_AF 250 ete 822       | 3704  TEXT_0A  304   ete  2280  2280
3688 TEXT_0A 250 ete 822     | 3705  TEXT_0A  304   ete  2350  2280
3708 TEXT_0A 300 ete 2250    | 3689  TEXT_0A  400   ete  3000  3000
3704 TEXT_0A 304 ete 2280    | 3717  TEXT_0A  400   ete  3002  3000
3705 TEXT_0A 304 ete 2350    | 3706  TEXT_0A  404   ete  3030  3030
3689 TEXT_0A 400 ete 3000    | 3696  TEXT_0A  500   ete  3750  3750
3717 TEXT_0A 400 ete 3002    | 3707  TEXT_0A  650   ete  4500  4875
3706 TEXT_0A 404 ete 3030    | 3720  TEXT_0A  800   ete  3000  6000
3696 TEXT_0A 500 ete 3750    | 3694  TEXT_0A  1000  ete  7500  7500
3707 TEXT_0A 649.5 ete 4500  | 
3720 TEXT_0A 800 ete 3000    | 
3694 TEXT_0A 1000 ete 7500   | 

过滤规则:

  1. 过滤包含字符串 _0A 的行并排除包含 DNTT _AF _XA 基于列 $3
  2. 基于列 $3 > 100 && $3
  3. 基于列 $3 > 200 && $3
  4. 如果列不相等,则在比较后将其过滤为预期输出 5 美元和 6 美元以下

预期输出:

3700  TEXT_0A  34    NA   NA    850
3721  TEXT_0A  55    ete  851   850
3701  TEXT_0A  100   NA   NA    850
3686  TEXT_0A  200   ete  822   1700
3716  TEXT_0A  200   ete  3000  1700
3688  TEXT_0A  250   ete  822   1875
3705  TEXT_0A  304   ete  2350  2280
3717  TEXT_0A  400   ete  3002  3000
3707  TEXT_0A  650   ete  4500  4875
3720  TEXT_0A  800   ete  3000  6000

部分工作代码:

awk '{if (( $2 ~ /_0A/ && !/DNTT|_AF|_XA/ && $3 <=100 )) \
printf ("%s %s %.0f %s %s %.0f\n",$1,$2,$3,$4,$5,850); \
else if (( $2 ~ /_0A/ && !/DNTT|_AF|_XA/ && $3 > 100 && $3 <=200 )) \
printf ("%s %s %.0f %s %s %.0f\n",$1,$2,$3,$4,$5,$3*8.5); \
else if (( $2 ~ /_0A/ && !/DNTT|_AF|_XA/ && $3 > 200 && $3 <=1000 )) \
printf ("%s %s %.0f %s %s %.0f\n",$1,$2,$3,$4,$5,$3*7.5)}' file2 | column -t

【问题讨论】:

  • 我不知道如何比较最后一步中的 $10 和 $11 列,或者如何轻松地进行比较
  • 您不能将其简化为一种情况,向您展示如何解决其他情况吗?而且,我们不能用 3-5 列和 2-5 条样本数据记录来解决这个问题吗?在此链接中搜索Before asking about problematic code 部分,然后在同一链接中搜索如何将坏脚本变成好问题 部分。祝你好运。
  • @shellter,好的,我会重写问题
  • 嗯,对不起,如果您今天阅读了我以前的 cmets,但我现在认为您的问题仍然需要改进。 (但对于提高你的 Q 来说是一个加分项)。由于您已从数据中删除了 DNTT|_AF|_XA,因此您应该从样本数据中删除它。当您尝试过滤掉这些数据时(无论如何),您可以将其视为grep -v 'DNTT|_AF|_XA' file | awk ....。你看到了吗,你已经消除了DNTT|_AF|_XA,你的逻辑根本不需要考虑这一点。现在出去购物了,以后再回来看看。祝你好运。
  • @shellter 嗨,感谢您指出使用 grep 的那个,但对我来说,关键问题是仅在相等的列号上显示非。 5+ 6 > 又名过滤规则 4,我缺少它来完成预期的输出,享受购物,谢谢

标签: awk numbers compare multiple-columns


【解决方案1】:

读取从 1 到 4 的行,并将其转换为 awk:

gawk '$0~"_0A" &amp;&amp; $0!~"DNTT"{ $6=(($3&gt;100 &amp;&amp; $3&lt;=200)?($3*8.5):($3&gt;200 &amp;&amp; $3&lt;=1000?($3*7.5):850)); if($5!=$6){ print }}' input.txt

输出:

3700 TEXT_0A 34 NA NA 850
3721 TEXT_0A 55 ete 851 850
3701 TEXT_0A 100 NA NA 850
3686 TEXT_0A 200 ete 822 1700
3716 TEXT_0A 200 ete 3000 1700
3688 TEXT_0A 250 ete 822 1875
3705 TEXT_0A 304 ete 2350 2280
3717 TEXT_0A 400 ete 3002 3000
3707 TEXT_0A 649.5 ete 4500 4871.25
3720 TEXT_0A 800 ete 3000 6000

if 语句 (if a=b then c else d;) 也可以写成 (a=b?c:d)

注意:你必须排除_AF _XA,我不清楚,因为没有看到_XA。这就是为什么我排除了DNTT

【讨论】:

    【解决方案2】:

    你可以使用这个awk:

    cat calc.awk
    
    $2 ~ /_0A/ && !/DNTT|_AF|_XA/ {
       if ( $3 <=100  )
          n = 850
       else if ( $3 > 100 && $3 <=200 )
          n = $3*8.5
       else if ( $3 > 200 && $3 <=1000 )
          n = $3*7.5
       if ($5 != n)   
          printf ("%s %s %.0f %s %s %.0f\n",$1,$2,$3,$4,$5,n)
    }
    

    然后将其用作:

    awk -f calc.awk file | column -t
    
    3700  TEXT_0A  34   NA   NA    850
    3721  TEXT_0A  55   ete  851   850
    3701  TEXT_0A  100  NA   NA    850
    3686  TEXT_0A  200  ete  822   1700
    3716  TEXT_0A  200  ete  3000  1700
    3688  TEXT_0A  250  ete  822   1875
    3705  TEXT_0A  304  ete  2350  2280
    3717  TEXT_0A  400  ete  3002  3000
    3707  TEXT_0A  650  ete  4500  4871
    3720  TEXT_0A  800  ete  3000  6000
    

    【讨论】:

    • 我试过它几乎可以工作,但是在输出中四舍五入时遇到问题,例如如果我将添加示例行“3717 TEXT_0A 141 ete 3000 1700 1198.5”,我尝试使用 printf 代替 { print } ("%s %s %s %s %s %0.f n\" $1,$2,$3,$4 ,$5,$6) 但它没有四舍五入,你知道放在哪里吗,与以前的解决方案有同样的问题,printf 0.f 不会向上取整
    猜你喜欢
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多