我有一个看起来像的文件:
chr1 mireap precursor 6405246 6405544 . - . ID=xxx-m0444;Count=3;mfe=-61.00
chr1 mireap mature-5p 6405511 6405534 . - . ID=xxx-m0444-5p;Parent=xxx-m044
chr1 mireap precursor 6482110 6482198 . + . ID=xxx-m0417;Count=105;mfe=-45.
chr1 mireap mature-5p 6482123 6482143 . + . ID=xxx-m0417-5p;Parent=xxx-m041
chr1 mireap mature-3p 6482168 6482188 . + . ID=xxx-m0417-3p;Parent=xxx-m041
chr1 mireap mature-3p 6482168 6482188 . + . Name=vvi-miR395g;ID=xxx-m0417-3
为澄清而大量编辑
当字段1,4和5在第二行重复时,我想在字段9的开头保留包含“名称”信息的重复行。字段9始终以“ID”或“名称”开头。我想删除字段9以“ID”开头的重复行。
例如,所需的输出如下所示:
chr1 mireap precursor 6405246 6405544 . - . ID=xxx-m0444;Count=3;mfe=-61.00
chr1 mireap mature-5p 6405511 6405534 . - . ID=xxx-m0444-5p;Parent=xxx-m044
chr1 mireap precursor 6482110 6482198 . + . ID=xxx-m0417;Count=105;mfe=-45.
chr1 mireap mature-5p 6482123 6482143 . + . ID=xxx-m0417-5p;Parent=xxx-m041
chr1 mireap mature-3p 6482168 6482188 . + . Name=vvi-miR395g;ID=xxx-m0417-3
根据'man sort',-u仅输出“同等运行”的第一行。我把它解释为......好吧,如果我只是反向排序而不是使用-u,那么将保留包含“Name”的行。
sort -k1,1 -k4,4n -rk5,5n file # Correctly sorts the file and the name line appears first relative to its duplicate.
sort -u -k1,1 -k4,4n -k5,5n -rk9,9 file # Runs, but still eliminates the "Name"-containing line anyway.
我也想过做这样的事情:
sort -k1,1 -k4,4n -rk5,5n file | awk '!x[$1,$4,%5]++' FS="\t" # but haven't gotten it to work quite yet and this still wouldn't retain the desired duplicate line...
想法?
答案 0 :(得分:4)
$ cat tst.awk
{ key = $1 FS $4 FS $5; isNameLine = ($9~/^Name=/ ? 1 : 0) }
NR==FNR { if (isNameLine) hasNameLine[key]; next }
isNameLine || !(key in hasNameLine)
$ awk -f tst.awk file file
chr1 mireap precursor 6405246 6405544 . - . ID=xxx-m0444;Count=3;mfe=-61.00
chr1 mireap mature-5p 6405511 6405534 . - . ID=xxx-m0444-5p;Parent=xxx-m044
chr1 mireap precursor 6482110 6482198 . + . ID=xxx-m0417;Count=105;mfe=-45.
chr1 mireap mature-5p 6482123 6482143 . + . ID=xxx-m0417-5p;Parent=xxx-m041
chr1 mireap mature-3p 6482168 6482188 . + . Name=vvi-miR395g;ID=xxx-m0417-3
答案 1 :(得分:0)
我的要求并不完全清楚, 但这里有一个简短的脚本,希望建议一个合适的实现。它的写作清晰而不是简洁。
首先让我们来定义" family"表示具有相同的一组线 [$ 1,$ 4,$ 5]价值。假设你总是想保留至少一个 "名称="一个家庭中的行,全局排序确实有意义 否则内存要求可能过高。
所以,让我们从您提出的那种开始,然后是awk 程序,您可能希望进一步调整,具体取决于 您的要求的详细信息和有关的详细信息 构造输入文件时遵循的约定:
Dictionary<string, int> ab = new Dictionary<string, int>
{
{"a", 1},
{"b", 0},
{"c", 3},
{"d", 0},
{"e", 5}
};
foreach(var pair in ab)
{
if(pair.Value != 0)
Console.WriteLine(pair.Key + "=" + pair.Value);
}
答案 2 :(得分:0)
使用sort
并首先按awk
惯用法选择,并根据“名称”的词汇顺序&gt; “ID”。
$ sort -k1,1 -k4,5 -k9,9r file | awk '!a[$1 FS $4 FS $5]++'
chr1 mireap precursor 6405246 6405544 . - . ID=xxx-m0444;Count=3;mfe=-61.00
chr1 mireap mature-5p 6405511 6405534 . - . ID=xxx-m0444-5p;Parent=xxx-m044
chr1 mireap precursor 6482110 6482198 . + . ID=xxx-m0417;Count=105;mfe=-45.
chr1 mireap mature-5p 6482123 6482143 . + . ID=xxx-m0417-5p;Parent=xxx-m041
chr1 mireap mature-3p 6482168 6482188 . + . Name=vvi-miR395g;ID=xxx-m0417-3
更新: 基于评论它看起来像$ 9的ID部分也应该是关键。由于没有测试数据,请验证
$ sort -k1,1 -k4,5 -k9,9r file
| awk '{match($9,/(ID=[^;]+;)/,m)}
!a[$1 FS $4 FS $5 FS m[1]]++'