如何找到一个txt文件单个条目?(How to find single entries in a t

2019-10-18 08:52发布

我有12列的txt文件。 有些线路是重复的,有些则不是。 作为一个例子我复制到我的数据的前4列。

0       0       chr12   48548073  
0       0       chr13   80612840
2       0       chrX    4000600 
2       0       chrX    31882528 
3       0       chrX    3468481 
4       0       chrX    31882726
4       0       chr3    75007624

基于第一列中,可以看到一些有除了进入副本“3”。 我想打印仅需单次项,在此情况下,“3”。

输出将是

3       0       chrX    3468481

有没有使用awk或Perl这样的快捷方式? 我只能想到使用Perl中环,但因为我有大约150万项,它可能会需要一段时间的事实。

Answer 1:

试试这个AWK一行代码:

awk '{a[$1]++;b[$1]=$0}END{for(x in a)if(a[x]==1)print b[x]}' file


Answer 2:

这里是另一种方式:

uniq -uw8 inputFile
  • -w8将为独特的前8个字符 (这是你的第一列)进行比较。
  • -u选项将打印只出现一次线。

测试:

$ cat file
0       0       chr12   48548073  
0       0       chr13   80612840
2       0       chrX    4000600 
2       0       chrX    31882528 
3       0       chrX    3468481 
4       0       chrX    31882726
4       0       chr3    75007624

$ uniq -uw8 file
3       0       chrX    3468481 


Answer 3:

没有一个班轮,但这个小Perl脚本来完成相同的任务:

#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';

# get filehandle
open( my $fh, '<', 'test.txt');

# all lines from your file
my %line_map; 

while( my $line = <$fh> ) { # read a line

   my $key;
   my @values;

   # split on whitespace
   ($key, @values) = split(/\s+/, $line);

   # delete a line if it already exists in the map
   if( exists $line_map{$key} ) {
       delete $line_map{$key};
   } 
   else { # mark a line to show that it has been seen
      $line_map{$key} = join("\t", @values);
   }
}

# now the map should only contain non-duplicates
for my $k ( keys %line_map ) {
   print "$k\t", $line_map{$k}, "\n"; 
}


Answer 4:

无法为注释正确格式。 @JS 웃可能依靠GNU uniq ...这似乎在BSD衍生版本一起使用:

grep ^`cut -d" " -f1 col_data.txt  | uniq -u` file.txt

有简单的必须是一个较短的perl回答:-)



Answer 5:

我知道必须有一个perl一个班轮响应。 这里是-没有大量测试,因此买者自负 ;-)

perl -anE 'push @AoA,[@F]; $S{$_}++ for @F[0];}{for $i (0..$#AoA) {for $j (grep {$S{$_}==1} keys %S) {say "@{$AoA[$i]}" if @{$AoA[$i]}[0]==$j}}' data.txt

这种方法的缺点是,它在输出稍微修改格式的数据(这是很容易解决,我认为),它使用两个for循环和“蝴蝶经营者”(!!)它还使用grep()其引入了一个隐含的循环 - 这些代码,即使你没有编写一个简单的循环自己),所以它可能是150万条记录慢速运行i..e之一。 我想看看它相比awkuniq虽然。

在加方不使用模块和应用在Windows和OSX上运行。 它的工作原理时,有独特的第一列几十个类似的记录,而且不需要前检查独特的行进行排序的输入。 该解决方案主要是从靠近末端的一个班轮例子那儿剽窃有效Perl编程约瑟夫·霍尔,荷兰Joh麦克亚当斯和布莱恩d FOY (一个伟大的书本-当智能匹配~~given when尘埃落定,我希望新版本出现):

下面是它的(我认为)工作原理:

  • 因为我们使用的-a我们得到的@F免费数组所以使用它,而不是分裂
  • 因为我们使用-n我们是一个内while() {}循环,所以push的元件@F@AoA作为参考的匿名阵列(在[]充当“匿名数组构造” )。 这样,他们流连,我们可以稍后再引用它们(这是否甚至意义???)
  • 使用$seen{$_}++成语(我们使用$S代替$seen )从上面提到和描述的那么好由书@Axeman这里SO看的独特元素@F[0]并设置在我们的/增量键%S根据多少次,我们看到与给定值( 行内容)的元素(或线)哈希值。
  • 使用一个“蝴蝶” }{打出来的的while ,然后,在一个单独的块,我们使用了两个for循环要经过外阵列并检查每个元素(它们本身是匿名数组$i -每个线)和然后,针对每个内部匿名数组, grep哪些值与去keys是等于“1” %S我们先前创建散列(在for $j (grep {$S{$_}==1} keys %S) ,或内循环),并连续将这些值在$j
  • 最后,我们通过外阵列迭代并打印任何匿名阵列,其中该阵列的第一个元素等于每个的值( $j )。 我们这样做有:( @{$AoA[$i]}[0]==$j )。

awk在@Kent手里有点更简练。 如果任何人有如何缩短或记录我的“线路噪声”的建议(我从来不说一下perl !)请加建设性的意见!

谢谢阅读。



文章来源: How to find single entries in a txt file?