基本上我想在第 2 列中具有相同值的行中应用 if 条件。在示例中,前三行在第 2 列 (Disease1) 中具有相同的值。现在,对于这三行,我想应用 IF 条件 - 如果第三列为“高”,则仅将该行写入输出文件。如果第三列没有“高”,则查找“中”并打印它。如果“中”也不存在,则打印包含“低”值的行。
输入:
id1 Disease1 High
id2 Disease1 Medium
id3 Disease1 Low
id4 Disease2 Low
id5 Disease3 Medium
id6 Disease3 Low
预期输出:
id1 Disease1 High
id4 Disease2 Low
id5 Disease3 Medium
答案1
awk 'BEGIN { FS=OFS="\t"; d["High"]=1; d["Medium"]=2; d["Low"]=3 } { print d[$3], $0 }' file |
sort -t $'\t' -k3,3 -k1,1n | sort -t $'\t' -s -u -k3,3 | cut -f 2-
不幸的是,单词“High”、“Medium”和“Low”并未按此顺序按字母顺序排序,因此我们在每行前面为第 3 列中的相应单词添加整数 1、2 和 3。awk
脚本。该整数与原始内容之间用制表符分隔,表示疾病的严重程度(1 最高)。
然后,我们对疾病和该整数字段的修改数据进行排序,以便记录按疾病分组并按严重程度排序。
然后,我们仅将疾病作为关键(第二个sort
)进行“独特排序”。这会丢弃任何重复的疾病,对于每种疾病,我们只留下最严重的记录。它们使用稳定的排序算法,保留具有相同键的记录的重新排序-s
。sort
最后cut
的 删除了我们之前添加的整数awk
。
管道假定使用 来bash
指定命令的字段分隔符sort
。如果bash
未使用,请插入单引号文字制表符而不是使用$'\t'
(您可能可以通过按 来执行此操作Ctrl+V Tab)。
答案2
如果每个 Id(以秒为单位)列的优先级始终从高到低,那么可以通过以下方式轻松完成:
sort -u -k2,2 infile
否则你可以这样做:
sed 's/High$/1/; s/Medium$/2/; s/Low$/3/' infile \
| sort -k2,3 \
| sort -uk2,2 \
| sed 's/1$/High/; s/2$/Medium/; s/3$/Low/'
或者只是awk
:
awk '{ pr[$2]=($3=="High"?$3:(pr[$2]=="High"?pr[$2]:(pr[$2]=="Medium"?pr[$2]:$3)));
if (temp!=pr[$2]) { id[$2]=$0; temp=pr[$2] }
} END { for (key in id) print id[key] }' infile
答案3
我将使用 Perl 并构建一个解析器,这将创建这个哈希:
- 第 2 列值作为键
- 对应于键的第一行将构成该键的值
- 设置值后,将跳过某个键的所有其他行
解析完成后,我将打印哈希值,如果需要的话对第二个标记进行排序。
答案4
只需 awk
awk '
BEGIN {prio["High"]=1; prio["Medium"]=2; prio["Low"]=3}
!($2 in p) || prio[$3] < p[$2] {p[$2] = prio[$3]; line[$2] = $0}
END {for (key in line) print line[key]}
' file
id1 Disease1 High
id4 Disease2 Low
id5 Disease3 Medium