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