【问题标题】:keep some lines of a file according to some conditions根据某些条件保留文件的某些行
【发布时间】:2015-07-01 07:21:09
【问题描述】:

我有一个这样的文件:

K1   bla   STARTED
K1   bla   FINISHED
K2   blu   FINISHED
K3   bli   STARTED
K3   bli   DIED_SKIPPED_PERMANENTLY
K4   blo   STARTED
K5   ble   STARTED
K5   ble   DIED_SKIPPED_PERMANENTLY
K6   blou  STARTED
K6   blou  STARTED

据此,我想获得一个文件,当第 1 列中的每个名称都有 FINISHEDDIED_SKIPPED_PERMANENTLY 时,只存在包含此信息的行而不存在其他行(带有 STARTED 或其他内容)。 此外,如果两行相同(如 K6 的那一行),我只想打印一个。

在我的示例中,输出将是:

K1   bla   FINISHED
K2   blu   FINISHED
K3   bli   DIED_SKIPPED_PERMANENTLY
K4   blo   STARTED
K5   ble   DIED_SKIPPED_PERMANENTLY
K6   blou  STARTED

我不能只删除

grep -v STARTED 

因为对于某些名称,例如我的示例中的 K4,只有这一行存在,我想知道它是否开始(或不开始),所以我需要保留该信息。

我有一个文件,其中包含我从第 1 列获得的所有名称:

awk '{print $1}' file | sort | uniq > names    # 7,752 lines

我在想那种循环:

对于文件“names”中存在的每个名称,请执行以下操作:

如果带有 $line 的行之一包含 FINISHEDDIED_SKIPPED_PERMANENTLY,则在我的输出中仅打印该行而不打印其他行。 否则,保留包含该名称的所有行。 但删除相同的行。

这是这个想法,但我不知道我该怎么做。 如果有人可以提供帮助,我将不胜感激

【问题讨论】:

  • only the line containing this information is present and not the other ones (with STARTED or other things) 但你的输出确实有STARTED?你什么意思?

标签: bash while-loop grep line


【解决方案1】:
awk '$3 ~ /FINISHED|DIED_SKIPPED_PERMANENTLY/ && !a[$0]++' input

这只是检查第三列是否匹配 FINISHED 或 DIED_SKIPPED_PERMANENTLY 并将整行存储在数组 a 中,仅在第一次看到时打印。请注意,这将打印第三列包含“FOO_FINISHED”的行,但这应该不是问题。但是,鉴于提供的示例输出,我认为您实际上正在寻找:

awk '$1!=p && NR>1{print l}; {p=$1;l=$0}END{ if($1!=p)print l}' input

当第 1 列中的键连续出现时,打印第 1 列中出现给定字段的最后一行。

【讨论】:

  • 这不打印开始行,最后还有一个流浪的/
  • 不,它不打印匹配“STARTED”的行。它与问题中给出的描述相匹配,而不是提供的输出,这是不一致的。
【解决方案2】:

使用 awk 和数组

awk '!a[$1]||/DIED_SKIPPED_PERMANENTLY|FINISHED/{a[$1]=$0}END{for(i in a)print a[i]}' f

输出

K1   bla   FINISHED
K2   blu   FINISHED
K3   bli   DIED_SKIPPED_PERMANENTLY
K4   blo   STARTED
K5   ble   DIED_SKIPPED_PERMANENTLY
K6   blou  STARTED

请注意,这是为了获得您发布的预期输出,但不适用于实际描述。

【讨论】:

    【解决方案3】:

    我们可以使用 STARTED 在字典上大于 FINISHEDDIED_SKIPPED_PERMANENTLY 的事实并使用

    sort filename | awk '!seen[$1,$2]++'
    

    因为STARTED 在字典上是最大的,所以当sort 完成时,STARTED 行将始终出现在FINISHEDDIED_SKIPPED_PERMANENTLY 行之后。 awk 代码遍历如此排序的行,并仅打印之前没有看到字段 1 和 2 组合的那些行。

    【讨论】:

      猜你喜欢
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 2020-09-28
      • 1970-01-01
      • 1970-01-01
      • 2016-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多