unix 删除重复次数超过n次的行

dojqjjoe  于 2023-01-20  发布在  Unix
关注(0)|答案(2)|浏览(162)

我想删除前3列中重复超过3次(或4次)的行。主要目标是删除基因组坐标重复超过3或4次的行。
输入文件.tsv
| chrome |位置|位置2|参考|阿尔特|
| - ------|- ------|- ------|- ------|- ------|
| 染色体21|小行星1046|小行星1046|T型|C级|
| 染色体21|小行星1046|小行星1046|T型|C级|
| 染色体21|小行星1046|小行星1046|A类|G级|
| 染色体21|小行星1046|小行星1046|C级|G级|
| 染色体21|小行星1046|小行星1046|A类|G级|
| 染色体21|小行星1046|小行星1046|T型|C级|
| 染色体21|小行星10465|小行星10465|T型|C级|
n=3时的预期输出
| chrome |位置|位置2|参考|阿尔特|
| - ------|- ------|- ------|- ------|- ------|
| 染色体21|小行星1046|小行星1046|T型|C级|
| 染色体21|小行星1046|小行星1046|T型|C级|
| 染色体21|小行星10465|小行星10465|T型|C级|
我尝试了awk '{if(!seen[$1,$2,$3]++){if(++count[$1,$2,$3]〈=3)print} }'和一些排序和uniq组合,但是它们没有得到我想要的输出。

dddzy1tm

dddzy1tm1#

使用dup计数进行注解可以让我们轻松地解决这个问题。
Python将比awk更方便。

import csv
import typer

def get_annotated_rows(sheet, prefix_length=3):
    """Generates (count, row) tuples.

    Count for a row will be 1 if this is the first time we've seen it,
    and increments with each duplicate row.
    We assess duplicates by examining just an initial prefix of each row.
    """
    prev = None
    count = 0
    for row in sheet:
        prefix = row[:prefix_length]
        if prefix != prev:
            prev = prefix
            count = 1
        else:
            count += 1
        yield count, row

def main(infile: str = "input_file.tsv", n: int = 4):
    with open(infile) as fin:
        sheet = csv.reader(fin, delimiter="\t")
        for count, row in get_annotated_rows(sheet):
            if count <= n:
                print("\t".join(row))

if __name__ == '__main__':
    typer.run(main)

install

$ pip install typer
wvt8vs2t

wvt8vs2t2#

一个常见的shell脚本技巧是重新格式化数据,以便使用 *nix实用程序轻松处理数据。通常,麻烦的实用程序是uniq命令,其名称为-f(跳过f字段选项),其中字段在记录的前面跳过。很多时候,您希望可以在记录的末尾跳过,因此我们依赖于awk来重新格式化数据以在末尾具有可跳过字段:

#!/bin/bash

awk 'NR>1{print $4 " " $5 " " $1 "_" $2 "_" $3 }' data.txt \
| sort -k3 | uniq -cf2 \
| awk '$1<3{
  split($4,arr,"_")
  for (i=1;i<=$1;i++) {
    print arr[1]"\t" arr[2]"\t" arr[3]"\t" $2 " " $3
  }
}'

产出

chr21   10464942        10464942        T C
chr21   10464942        10464942        T C
chr21   10465086        10465086        T C

可以根据需要更改print语句中的字段分隔符,以满足使用系统的需要。
(And该代码可以被折叠到一行上,给出非常期望的(如果被错误地赋值)“oneliner”(-:)。

相关问题