我有一个这样的档案:
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列中的每个名称都有FINISHED
或DIED_SKIPPED_PERMANENTLY
时,只有包含此信息的行存在而不存在其他行(带有开始或其他事情)。
此外,如果两条线相同(如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
包含FINISHED
或DIED_SKIPPED_PERMANENTLY
,则只在我的输出中打印该行,而不打印其他行。
否则,请保留包含该名称的所有行。
但是删除相同的行。
这是一个想法,但我不知道如何做到这一点。 如果有人可以提供帮助,我将不胜感激
答案 0 :(得分:1)
我们可以使用STARTED
按字典顺序大于FINISHED
和DIED_SKIPPED_PERMANENTLY
并使用
sort filename | awk '!seen[$1,$2]++'
由于STARTED
在字典上最大,因此在STARTED
完成后,FINISHED
或DIED_SKIPPED_PERMANENTLY
行后将始终显示sort
行。 awk代码通过如此排序的行趟过,只打印那些之前没有看到字段1和2的组合的行。
答案 1 :(得分:0)
使用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
请注意,这是为了获得您已发布的预期输出,但不适用于实际描述。
答案 2 :(得分:0)
awk '$3 ~ /FINISHED|DIED_SKIPPED_PERMANENTLY/ && !a[$0]++' input
这只是检查第3列是否匹配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列中出现给定字段的最后一行。