Linux 拾取共享某些列(但不是全部)的行

Linux 拾取共享某些列(但不是全部)的行,linux,sorting,awk,unique,Linux,Sorting,Awk,Unique,我正在尝试修改一个文件,该文件有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

我正在尝试修改一个文件,该文件有
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
位于此处,因为它与
1.txt
文件中的
2.line
共享第一列
5
。它在最后一列上的数字是最低的(
-1.1<1.1
,对于最后一行,我们保留
-8.1
,因为它小于
11.1
),所以我们只保留它,并且我们保留其他没有相同的前
5
字段的行。 我尝试的是在
awk
中将第一列
5
保留为
index
,但它只打印唯一的列,而不打印其余的列。并且它不会选择最后一列中数字最低的行。 守则:

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
列的行,这些列在最后一列上的值最低。
谢谢你的帮助

awk
救援!(借助于
排序

使用共享键(字段1到5)对记录进行排序分组,并按数字升序的第七个字段对它们进行排序(因此第一个字段的值最小);通过管道传输到
awk
以获取给定键的第一条记录(著名的
awk
习惯用法,您也在脚本中使用)

这里是另一种没有
awk

$ sort -k1,5 -k7n file | rev | uniq -f2 | rev
注意输出的顺序是不确定的。您始终可以通过管道将输出传输到排序,或使用GNU awk控制输出


我刚刚意识到
数组完全没有必要,但会消耗大量内存:
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
awk'
{key=$1fs$2fs$3fs$4fs$5}
!(输入最小值)| |$NF

由于交换,可能需要很长时间。

您是否可以解释一下?但是,如果我不想按第一个连续的列进行排序,而是按第1列、第4列和第5列进行排序,我该怎么做?如果键不连续,
uniq
解决方案将不起作用<如果您为这两个项都正确设置了键,则代码>排序/awk
对将起作用。您是如何根据最后一列上的值进行选择的?您能解释一下吗?我会记录最后一列的最小值:
$NF
谢谢!有没有办法让它更快?我的输入文件很大,需要花很多时间。大约有5000万
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
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