【问题标题】:Delete matching lines in two tab delimited files删除两个制表符分隔文件中的匹配行
【发布时间】:2018-09-11 05:02:49
【问题描述】:

我有 2 个制表符分隔文件

A 2
A 5
B 4
B 5
C 10

A 2
A 5
B 5

我想删除 file1 中 file2 中的行,以便输出为:

B 4
C 10

我试过了:

awk 'NR==FNR{c[$1$2]++;next};!c[$1$2] > 0' file2 file1 > file3 

但它删除的行数比预期的多。

1026997259 file1 
   1787919 file2 
1023608359 file3

如何修改这段代码,以便:

我有 2 个制表符分隔文件

A 2 3
A 5 4
B 4 5
B 5 5
C 10 12

A 2 5
A 5 4
B 5 3 
F 6 7

仅基于第 1 列和第 2 列,我想抓取 file1 中也在 file2 中的行,以便输出为:

B 5 5
C 10 12

【问题讨论】:

  • 嘿!我想发布一个新问题,但这只是对这个问题的修改。如何修改代码以便我可以获取两个文件之间不匹配的行而不是匹配的行?适用于包含多于这两列的文件的东西(参见上面的示例)。

标签: bash shell awk


【解决方案1】:

为什么不使用grep 命令?

grep -vf file2 file1

【讨论】:

  • 对不起。它不会:/ 它不会删除任何行。
  • 我刚刚在带有标签的文件上进行了测试,效果很好:)
  • 见我上面的评论。是的,这也有效。谢谢!
【解决方案2】:

想一想 - 如果你连接 ab ca cb 它们都变成 abc 那么你认为你的代码对 $1$2 做了什么?按预期使用 SUBSEP ($1,$2) 并将 !c[$1$2] > 0 更改为 !(($1,$2) in c)。还要考虑!c[$1$2] > 0 是指!(c[$1$2] > 0) 还是(!c[$1$2]) > 0。我永远不会写以前的代码,所以我肯定会写,我总是用括号写它,因为我打算解析它。这样做:

awk 'NR==FNR{c[$1,$2];next} !(($1,$2) in c)' file2 file1

或者只使用$0 而不是$1,$2

awk 'NR==FNR{c[$0];next} !($0 in c)' file2 file1

【讨论】:

  • 知道了!对于 awk 'NR==FNR{c[$0];next} !($0 in c)' file2 file1,我是否必须添加 BEGIN{FS=OFS="\t"} 和或 SUBSEP="\t"?它正在打印文件 3 中文件 1 的每一行。
  • 我问是因为我仍然从 file1 中删除了错误的行数。 1026997259 文件1、1787919 文件2、1025209759 文件3。
  • 不,鉴于您到目前为止告诉我们的内容并按照您的问题所示输入,您无需添加或更改任何内容,我发布的命令将完全按照您的要求执行。如果不是,那么您做错了什么,或者您的输入实际上与您发布的示例不同,那么您需要进一步调查并在需要帮助时发布正确的输入。
  • 是的。我认为输入文件有问题。其中之一已损坏。是的。有用!非常感谢。
【解决方案3】:

如果两个文件中的匹配行相同,并且两个文件的排序顺序相同,那么 comm(1) 可以解决问题:

comm -23 file1 file2

它打印出仅在第一个文件中的行(除非给出-1),仅在第二个文件中的行(除非-2),以及在两个文件中的行(除非-3 )。如果您启用了多个选项,则它们将打印在多个(制表符分隔的)列中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 2017-05-09
    相关资源
    最近更新 更多