bash - 如何根据第3列的唯一标识符打印第1列的第一行和第2列的最后一行

标签 bash sorting awk

我有一个制表符分隔的文件,如下所示:

Het 157709  157731  Cluster.90  2   +
Het 157739  157760  Cluster.90  2   +
Het 164238  164259  Cluster.97  10  +
Het 164380  164401  Cluster.97  10  +
Het 164396  164417  Cluster.97  10  +
Het 164397  164421  Cluster.97  10  +
Het 164397  164420  Cluster.97  10  +
Het 164399  164420  Cluster.97  10  +
Het 164536  164561  Cluster.97  10  +
Het 164576  164598  Cluster.97  10  +
Het 164599  164615  Cluster.97  10  +
Het 164635  164656  Cluster.97  10  +
Het 198007  198031  Cluster.125 3   +
Het 198007  198028  Cluster.125 3   +
Het 198011  198035  Cluster.125 3   +

我正在寻找一种生成如下文件的有效方法:

Het 157709  157760  Cluster.90  2   +
Het 164238  164656  Cluster.97  10  +
Het 198007  198035  Cluster.125 3   +

对于第 4 列中的每个唯一条目,我写了一行,其中包括第 1 列和第 2 列的第一行,然后是第 3、4、5 和 6 列的最后一行。到目前为止,我已经尝试了以下解决方案但它似乎效率很低:

for i in `awk '{print $4}' filename | sort | uniq`
    do
    fgrep -F $i -w filename | awk 'NR==1 {printf $1"\t"$2"\t"} END {print $3"\t"$4"\t"$5"\t"$6}' >>filename2
done

问题是,当我有一个巨大的文件(487559 行)时,这需要很长时间。是否有更好的解决方案隐藏在某人的头脑中?

最佳答案

仅当第 4 列中的唯一条目始终具有与第 5 列末尾相同的数据时,此一行才有效。你的例子就是这样,但在我看来并没有真正回答这个问题。尽管如此,FWIW:

paste <(uniq -f3 file | cut -f1,2) <(tac file | uniq -f3 | tac | cut -f3-)

uniq 有一个选项可以控制要比较唯一性的字符数,以及要跳过的前导字段数和要跳过的前导字符数,但不能控制要比较的字段。

关于bash - 如何根据第3列的唯一标识符打印第1列的第一行和第2列的最后一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22214000/

相关文章:

linux - 如何从 bash 脚本启动交互式 ssh 终端?

c# - 字符串排序陷阱

regex - 如果第二行包含与第一行相同的匹配项,我如何打印 2 行?

linux - 使用 AWK 比较两个不同的文件并将值从一个文件复制到另一个文件

python - 将 bash 变量传递给脚本?

linux - unix 将文件列表连接到线上

bash:在 DEBUG 陷阱中保留 $_

Java 字符串合并排序仅适用于最多四个元素的数组列表

c - 了解合并排序代码

awk - 如何在 awk 中替换整列而不丢失格式