Perl uniq第一个字段,不丢弃重复行的内容
这是我第一次面对这种情况。我只需要对第一个字段执行uniq,但不需要删除复制行的任何内容。就拿这个例子来说 输入文件Perl uniq第一个字段,不丢弃重复行的内容,perl,sed,awk,uniq,Perl,Sed,Awk,Uniq,这是我第一次面对这种情况。我只需要对第一个字段执行uniq,但不需要删除复制行的任何内容。就拿这个例子来说 输入文件 ENST000001.1 + 67208778 67210057 ENST000001.1 + 67208778 67210768 ENST000001.1 + 67208778 67208882 ENST000002.5 + 67208778 67213982 ENST000003.1 - 5746357
ENST000001.1 + 67208778 67210057
ENST000001.1 + 67208778 67210768
ENST000001.1 + 67208778 67208882
ENST000002.5 + 67208778 67213982
ENST000003.1 - 57463571 57463801
ENST000003.1 - 57476352 57476463
ENST000003.1 - 57476817 57476945
当我这样做(uniq-w12)时,只会在所有其他行中检查第一个字段(只有12个字符)。结果如下:
ENST000001.1 + 67208778 67210057
ENST000002.5 + 67208778 67213982
ENST000003.1 - 57463571 57463801
将丢弃所有重复行的内容,只保留第一行。我要找的是这样的东西
ENST000001.1 + 67208778_67210057 67208778_67210768 67208778_67208882
ENST000002.5 + 67208778_67213982
ENST000003.1 - 57463571_57463801 57476352_57476463 57476817_57476945
如何使用uniq而不丢失复制行的内容?!有没有一种在AWK/sed/perl中实现的方法
awk '{a[$1" "$2]=a[$1" "$2]" "$3" "$4;}END{for(i in a)print i,a[i]}' your_file
测试如下:
> cat temp
ENST000001.1 + 67208778 67210057
ENST000001.1 + 67208778 67210768
ENST000001.1 + 67208778 67208882
ENST000002.5 + 67208778 67213982
ENST000003.1 - 57463571 57463801
ENST000003.1 - 57476352 57476463
ENST000003.1 - 57476817 57476945
> awk '{a[$1" "$2]=a[$1" "$2]" "$3" "$4;}END{for(i in a)print i,a[i]}' temp
ENST000002.5 + 67208778 67213982
ENST000003.1 - 57463571 57463801 57476352 57476463 57476817 57476945
ENST000001.1 + 67208778 67210057 67208778 67210768 67208778 67208882
如果您对下划线(
)有明确要求,请使用以下命令:
> awk '{a[$1" "$2]=a[$1" "$2]" "$3"_"$4;}END{for(i in a)print i,a[i]}' temp
ENST000002.5 + 67208778_67213982
ENST000003.1 - 57463571_57463801 57476352_57476463 57476817_57476945
ENST000001.1 + 67208778_67210057 67208778_67210768 67208778_67208882
>
说明:
->创建一个关联数组a,其键将是第一个字段+空格+第二个字段
->每个键的值是其上一个值+第三个字段+下划线+第四个字段
->结束块在处理所有行之后执行。for循环将在整个数组中循环并打印其键和值
由于perl也被标记,以下是perl解决方案:
perl -F -lane '$H{$F[0]." ".$F[1]}=$H{$F[0]." ".$F[1]}." ".$F[2]."_".$F[3];if(eof){foreach(keys %H){print $_,$H{$_}}}' your_file
上面的perl解决方案在命令行本身上工作
测试如下:
> cat temp
ENST000001.1 + 67208778 67210057
ENST000001.1 + 67208778 67210768
ENST000001.1 + 67208778 67208882
ENST000002.5 + 67208778 67213982
ENST000003.1 - 57463571 57463801
ENST000003.1 - 57476352 57476463
ENST000003.1 - 57476817 57476945
> awk '{a[$1" "$2]=a[$1" "$2]" "$3" "$4;}END{for(i in a)print i,a[i]}' temp
ENST000002.5 + 67208778 67213982
ENST000003.1 - 57463571 57463801 57476352 57476463 57476817 57476945
ENST000001.1 + 67208778 67210057 67208778 67210768 67208778 67208882
如果您对下划线(
)有明确要求,请使用以下命令:
> awk '{a[$1" "$2]=a[$1" "$2]" "$3"_"$4;}END{for(i in a)print i,a[i]}' temp
ENST000002.5 + 67208778_67213982
ENST000003.1 - 57463571_57463801 57476352_57476463 57476817_57476945
ENST000001.1 + 67208778_67210057 67208778_67210768 67208778_67208882
>
说明:
->创建一个关联数组a,其键将是第一个字段+空格+第二个字段
->每个键的值是其上一个值+第三个字段+下划线+第四个字段
->结束块在处理所有行之后执行。for循环将在整个数组中循环并打印其键和值
由于perl也被标记,以下是perl解决方案:
perl -F -lane '$H{$F[0]." ".$F[1]}=$H{$F[0]." ".$F[1]}." ".$F[2]."_".$F[3];if(eof){foreach(keys %H){print $_,$H{$_}}}' your_file
上面的perl解决方案在命令行本身上工作。在perl中,您可以通过在hashref中将它们分组来完成
#!/usr/bin/perl
use strict;
use warnings;
my $lines;
while (<DATA>) {
chomp;
my @fields = split /\s+/;
push @{ $lines->{"$fields[0] $fields[1]"} }, "$fields[2]_$fields[3]";
}
foreach my $line (sort keys %$lines) {
print join("\t", $line, @{ $lines->{$line} }), "\n";
}
__DATA__
ENST000001.1 + 67208778 67210057
ENST000001.1 + 67208778 67210768
ENST000001.1 + 67208778 67208882
ENST000002.5 + 67208778 67213982
ENST000003.1 - 57463571 57463801
ENST000003.1 - 57476352 57476463
ENST000003.1 - 57476817 57476945
#/usr/bin/perl
严格使用;
使用警告;
我的$line;
而(){
咀嚼;
我的@fields=split/\s+/;
推送{$lines->{“$fields[0]$fields[1]”},“$fields[2]$fields[3]”;
}
foreach my$行(排序键%$行){
打印联接(“\t”,$line,@{$line->{$line}),“\n”;
}
__资料__
ENST00001.1+67208778 67210057
ENST00001.1+67208778 67210768
ENST00001.1+67208778 67208882
ENST00002.5+67208778 67213982
ENST00003.1-57463571 57463801
ENST00003.1-57476352 57476463
ENST00003.1-57476817 57476945
在Perl中,可以通过在hashref中对它们进行分组来实现
#!/usr/bin/perl
use strict;
use warnings;
my $lines;
while (<DATA>) {
chomp;
my @fields = split /\s+/;
push @{ $lines->{"$fields[0] $fields[1]"} }, "$fields[2]_$fields[3]";
}
foreach my $line (sort keys %$lines) {
print join("\t", $line, @{ $lines->{$line} }), "\n";
}
__DATA__
ENST000001.1 + 67208778 67210057
ENST000001.1 + 67208778 67210768
ENST000001.1 + 67208778 67208882
ENST000002.5 + 67208778 67213982
ENST000003.1 - 57463571 57463801
ENST000003.1 - 57476352 57476463
ENST000003.1 - 57476817 57476945
#/usr/bin/perl
严格使用;
使用警告;
我的$line;
而(){
咀嚼;
我的@fields=split/\s+/;
推送{$lines->{“$fields[0]$fields[1]”},“$fields[2]$fields[3]”;
}
foreach my$行(排序键%$行){
打印联接(“\t”,$line,@{$line->{$line}),“\n”;
}
__资料__
ENST00001.1+67208778 67210057
ENST00001.1+67208778 67210768
ENST00001.1+67208778 67208882
ENST00002.5+67208778 67213982
ENST00003.1-57463571 57463801
ENST00003.1-57476352 57476463
ENST00003.1-57476817 57476945
这里有一个Perl单行程序:
perl -lane 'BEGIN{$"=v9}push@{$u{"@F[0,1]"}},"$F[2]_$F[3]"}{while(($k,$v)=each%u){print"@{[$k,@$v]}"}'
扩展版本:
#!/usr/bin/env perl
use strict;
use warnings;
BEGIN { $/ = "\n"; $\ = "\n"; $" = "\t" }
my %u;
while (<ARGV>) {
chomp;
my @F = split /\s+/;
push @{$u{"@F[0, 1]"}}, "$F[2]_$F[3]";
}
while (my ($k, $v) = each %u) {
print "@{[$k, @$v]}";
}
#/usr/bin/env perl
严格使用;
使用警告;
开始{$/=“\n”;$\=“\n”;$”=“\t”}
我的%u;
而(){
咀嚼;
my@F=split/\s+/;
推送{$u{“@F[0,1]”},“$F[2]”和{$F[3]”;
}
而(我的($k,$v)=每个%u){
打印“@{[$k,@$v]}”;
}
这里有一个Perl单行程序:
perl -lane 'BEGIN{$"=v9}push@{$u{"@F[0,1]"}},"$F[2]_$F[3]"}{while(($k,$v)=each%u){print"@{[$k,@$v]}"}'
扩展版本:
#!/usr/bin/env perl
use strict;
use warnings;
BEGIN { $/ = "\n"; $\ = "\n"; $" = "\t" }
my %u;
while (<ARGV>) {
chomp;
my @F = split /\s+/;
push @{$u{"@F[0, 1]"}}, "$F[2]_$F[3]";
}
while (my ($k, $v) = each %u) {
print "@{[$k, @$v]}";
}
!/usr/bin/env perl
严格使用;
使用警告;
开始{$/=“\n”;$\=“\n”;$”=“\t”}
我的%u;
而(){
咀嚼;
my@F=split/\s+/;
推送{$u{“@F[0,1]”},“$F[2]”和{$F[3]”;
}
而(我的($k,$v)=每个%u){
打印“@{[$k,@$v]}”;
}
这可能适合您(GNU-sed):
sed-r:a;$!Ns/^((\s+\s+\s+.*)\n\2/\1/;助教;s/\/\1\u2/g;PD'文件
这可能适合您(GNU-sed):
sed-r:a;$!Ns/^((\s+\s+\s+.*)\n\2/\1/;助教;s/\/\1\u2/g;PD'文件
你能给我解释一下你的awk线路吗?你能给我解释一下你的awk线路吗?