根据某些条件保留文件的某些行



我有一个这样的文件:

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

我在想一个这样的循环:

对于文件"名称"中存在的每个名称,执行:

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

这是我的想法,但我不知道该怎么做。如果有人能帮助,我将不胜感激

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

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

因为STARTED在字典上是最大的,所以当sort完成时,STARTED行将总是出现在FINISHEDDIED_SKIPPED_PERMANENTLY行之后。awk代码遍历如此排序的行,只打印那些以前没有看到字段1和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

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

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中出现给定字段的最后一行。

相关内容

  • 没有找到相关文章

最新更新