我正在尝试修改包含7
列的文件。
输入文件示例为:
1.txt
1 10 11 A L X3 -1.1
1 10 11 A L X1 1.1
1 13 21 A T X3 -2.1
3 11 12 A T X2 -3.1
3 11 12 K T X2 7.1
4 11 12 A T X7 -8.1
4 11 12 C T X7 -8.1
4 11 12 C T X7 11.1
我想提取共享前5列的这些行,但最后两列不同,而其他不共享前5列的行。然后,我想在最后一列保留最低值的行。
预期输出为:
1 10 11 A L X3 -1.1
1 13 21 A T X3 -2.1
3 11 12 A T X2 -3.1
3 11 12 K T X2 7.1
4 11 12 A T X7 -8.1
4 11 12 C T X7 -8.1
1st line
在此处,因为它与5
文件中的2.line
共享第一个1.txt
列。并且它在最后一列(-1.1 < 1.1
上的数字最小,而且对于最后一行,我们保留一个-8.1
,因为它小于11.1
),所以我们只保留它,我们保持其他第一个5
字段不相同的行。
我尝试过的是将5
列中的第index
列保留为awk
中的awk -F"\t" '!seen[$1,$2,$3,$4,$5]++' 1.txt
,但它只打印唯一的列,而不是其余的列。并且它不会选择最后一列中编号最小的行。
代码:
1 10 11 A L X3 -1.1
1 10 11 A L X1 1.1
1 13 21 A T X3 -2.1
3 11 12 A T X2 -3.1
3 11 12 K T X2 7.1
4 11 12 A T X7 -8.1
4 11 12 C T X7 -8.1
4 11 12 C T X7 11.1
其输出:
5
我无法选择仅共享第一列{{1}}列的行,这些列在最后一列上具有最低值。 感谢您的帮助!
答案 0 :(得分:3)
awk
救援! (在sort
)
$ sort -k1,5 -k7n file |
awk '!a[$1,$2,$3,$4,$5]++'
1 10 11 A L X3 -1.1
1 13 21 A T X3 -2.1
3 11 12 A T X2 -3.1
3 11 12 K T X2 7.1
4 11 12 A T X7 -8.1
4 11 12 C T X7 -8.1
对具有共享密钥(字段1到5)的记录进行排序,并按数字上升的第七个字段对它们进行排序(因此第一个字段具有最小值);通过管道传输到awk
来获取给定密钥的第一条记录(着名的awk
成语,您也在脚本中使用了。)
这是另一种没有awk
$ sort -k1,5 -k7n file | rev | uniq -f2 | rev
答案 1 :(得分:1)
awk '
{key = $1 FS $2 FS $3 FS $4 FS $5}
!(key in min) || $NF < min[key] {min[key] = $NF; line[key] = $0}
END {for (key in line) print line[key]}
' file
1 10 11 A L X3 -1.1
1 13 21 A T X3 -2.1
4 11 12 C T X7 -8.1
4 11 12 A T X7 -8.1
3 11 12 K T X2 7.1
3 11 12 A T X2 -3.1
请注意输出的顺序是不确定的。您始终可以将输出传递给sort
,或使用GNU awk并控制array traversal。
我刚刚意识到line
数组完全不必要,但会消耗大量内存:min
数组将前5个字段作为键,第6个字段作为值
awk '
{key = $1 FS $2 FS $3 FS $4 FS $5}
!(key in min) || $NF < min[key] {min[key] = $NF}
END {for (key in line) print key, min[key]}
' file
由于交换可能需要很长时间。