2015-04-02 238 views
1

是否可以使用awk从文件中删除行?我想找到最后一列中有Y的行,然后删除与该行第2列中的值相匹配的行。使用AWK删除特定行[或sed,grep,whatever]

前:

KEY1,TRACKINGKEY1,TRACKINGNUMBER1-1,PACKAGENUM1-1,N 
    ,TRACKINGKEY1,TRACKINGNUMBER1-2,PACKAGENUM1-2,N 
KEY1,TRACKINGKEY1,TRACKINGNUMBER1-1,PACKAGENUM1-1,Y 
    ,TRACKINGKEY1,TRACKINGNUMBER1-2,PACKAGENUM1-2,Y 
KEY1,TRACKINGKEY5,TRACKINGNUMBER1-3,PACKAGENUM1-3,N 
KEY2,TRACKINGKEY2,TRACKINGNUMBER2-1,PACKAGENUM2-1,N 
KEY3,TRACKINGKEY3,TRACKINGNUMBER3-1,PACKAGENUM3-1,N 
    ,TRACKINGKEY3,TRACKINGNUMBER3-2,PACKAGENUM3-2,N 

所以AWK会发现该行有3中的Y最后一列,然后再看列2 TRACKINGKEY1]和删除具有TRACKINGKEY1在列中的所有行2.

预期结果:

KEY1,TRACKINGKEY5,TRACKINGNUMBER1-3,PACKAGENUM1-3,N 
KEY2,TRACKINGKEY2,TRACKINGNUMBER2-1,PACKAGENUM2-1,N 
KEY3,TRACKINGKEY3,TRACKINGNUMBER3-1,PACKAGENUM3-1,N 
    ,TRACKINGKEY3,TRACKINGNUMBER3-2,PACKAGENUM3-2,N 

这样做的原因是,我们的船ping程序会在处理货件时发出文件,以及何时该货件无效[出现错误时]。所以我最终得到的是最初的包裹信息,然后是表明它已经无效的相同信息,然后是另一组包含新货件信息的行。不幸的是,我们的ERP软件有一个相当简单的脚本语言,我甚至无法制作数组,因此我仅限于shell工具。

在此先感谢!

回答

1

的一种方法是使用awk来取2个传递给同一个文件:

awk -F, 'NR == FNR && $NF=="Y" && !($2 in seen){seen[$2]} 
      NR != FNR && !($2 in seen)' file file 
KEY1,TRACKINGKEY5,TRACKINGNUMBER1-3,PACKAGENUM1-3,N 
KEY2,TRACKINGKEY2,TRACKINGNUMBER2-1,PACKAGENUM2-1,N 
KEY3,TRACKINGKEY3,TRACKINGNUMBER3-1,PACKAGENUM3-1,N 
    ,TRACKINGKEY3,TRACKINGNUMBER3-2,PACKAGENUM3-2,N 

说明:

NR == FNR     # if processing the file 1st time 
&& $NF=="Y"     # and last field is Y 
&& !($2 in seen) {   # we haven't seen field 2 before 
    seen[$2]}     # store field 2 in array seen 
} 
NR != FNR     # when processing the file 2nd time 
&& !($2 in seen)    # array seen doesn't have field 2 
          # take default action and print the line 
+1

当NR == FNR时,如果我们之前没有看过它,没关系。不错的解决方案。 – 2015-04-02 20:44:09

1

该解决方案是一种严重的,但一种乐趣。

grep ',Y$' file | cut -d, -f2 | sort -u | grep -vwFf - file 
  • grep ',Y$' file - 找到Y上的线最后一列
  • cut -d, -f2 - 打印刚刚从这些行
  • 跟踪密钥
  • sort -u - 仅仅给出了独特的按键
  • grep -vwFf - file -
    • 从标准输入读取唯一的跟踪键(-f -
    • 只考虑他们的比赛,如果他们是整个单词(-w
    • 它们是固定的字符串,而不是正则表达式(-F
    • 然后排除行从文件中匹配这些模式(-v