如何根据特定的列值有选择地删除串联重复行?

时间:2019-04-09 03:39:21

标签: awk grep

我是命令行文本编辑(如awk和grep)中的豌豆。我有一个表数组,想根据第4列中的值删除行。我想删除第4列中包含值1的所有行,然后在下一行中删除相同的值。

这是数据列表,

k141    4797    2466    1
k141    4797    2466    2
k141    23474   11850   1
k141    27428   13800   1
k141    31736   15974   1
k141    35202   17751   1
k141    35202   17751   2
k141    35202   17751   3
k141    35202   17751   4
k141    35202   17751   5
k141    35202   17751   6
k141    35202   17751   7
k141    35202   17751   8
k141    35202   17751   9
k141    46266   23337   1
k141    54599   27445   1
k141    56753   28564   1
k141    56753   28564   2
k141    63661   32007   1
k141    71561   35988   1
k141    71561   35988   2
k141    72661   36561   1
k141    73579   37039   1
k141    84106   42358   1
k141    87251   43930   1
k141    88405   44516   1
k141    88405   44516   2
k141    88405   44516   3
k141    88405   44516   4
k141    89270   44939   1
k141    89270   44939   2
k141    89270   44939   3
k141    89270   44939   4
k141    93137   46825   1
k141    97378   48980   1
k141    97378   48980   2

我的预期输出是:

k141    4797    2466    1
k141    4797    2466    2
k141    35202   17751   1
k141    35202   17751   2
k141    35202   17751   3
k141    35202   17751   4
k141    35202   17751   5
k141    35202   17751   6
k141    35202   17751   7
k141    35202   17751   8
k141    35202   17751   9
(removal here)
k141    56753   28564   1
k141    56753   28564   2
(removal here)
k141    71561   35988   1
k141    71561   35988   2
(removal here)
k141    88405   44516   1
k141    88405   44516   2
k141    88405   44516   3
k141    88405   44516   4
k141    89270   44939   1
k141    89270   44939   2
k141    89270   44939   3
k141    89270   44939   4
(removal here)
k141    97378   48980   1
k141    97378   48980   2

大多数在线方法将删除第4列中等于1的以下所有行,例如awk !($4 in a){a[$4]++; next} $4 in a文件

因此,如果有人可以提出建议,我将不胜感激。

2 个答案:

答案 0 :(得分:0)

这应该做到:

awk '$4=="1"{o=$0;next;}{if(o)print o;o=0}1' file.txt

它如何工作?

删除重复项,打印最后一个重复项,打印所有其他行。

$4=="1" { o=$0; next;}

如果第4列等于1,然后将整行分配给变量o,然后读取下一行。 (这基本上删除了重复项,将最后一个保存在o中。)

{if(o)print o;o=0}

对于与上述条件不匹配的行,请打印变量o(最后一个重复项)并重置o以重复此过程。

1

打印当前行。

答案 1 :(得分:0)

使用uniqman uniq

NAME
       uniq - report or omit repeated lines

       -f, --skip-fields=N
              avoid comparing the first N fields

使用uniquniq将选择第一个重复的值:

$ cat foo
1 1
2 2
3 2
4 3
$ uniq -f 1 foo
1 1
2 2
4 3

显然您需要最后一个,所以我们需要使用tacman tacuniq连接并反向打印文件 >

$ tac file | uniq -f 3 | tac
k141    4797    2466    1
k141    4797    2466    2
k141    35202   17751   1
k141    35202   17751   2