我有一个看起来像的文件:
chr start end fold_enrichment
1 760605 769233 15.65
1 760605 769233 44.11
1 760605 769233 18.5
1 760605 769233 11.38
1 947714 951356 110.99
1 1404923 1410311 96.76
1 1404923 1410311 27.04
我想编写一个逐行遍历文件的perl脚本,并将每行与前一行(或下一行)进行比较,以查找前3列中的匹配值。然后我想只在前三列打印一次值,第四列值作为新列推送。
例如,我想采取
1 760605 769233 15.65
1 760605 769233 44.11
1 760605 769233 18.5
并打印
1 760605 769233 15.65 44.11 18.5
谢谢!
答案 0 :(得分:2)
perl -ape '$k="@F[0..2]"; $_=" $F[3]",next if $k eq $o; $_= "\n@F";$o=$k' file
输出
1 760605 769233 15.65 44.11 18.5 11.38
1 947714 951356 110.99
1 1404923 1410311 96.76 27.04
答案 1 :(得分:1)
正如鲍罗丁所说,SO不是免费服务。请始终展示您的工作并解释您遇到问题的地方。
然而,是的,偶尔我们中的一些人会因为它的乐趣而更加慷慨。 perl one-liner:
perl -0777 -pe "1 while (s/^(\S+\s+\S+\s+\S+) (.*?)\s*\n\1 (.*)/$1 $2 $3/mg)" data.txt
输出:
chr start end fold_enrichment
1 760605 769233 15.65 44.11 18.5 11.38
1 947714 951356 110.99
1 1404923 1410311 96.76 27.04
答案 2 :(得分:1)
以下是我对单行的尝试:
perl -lane '$k="@F[0..2]"; push @o,$k if !$h{$k}; push @{$h{$k}},$F[3] }{ print "$_ @{$h{$_}}" for @o' file
输出
chr start end fold_enrichment
1 760605 769233 15.65 44.11 18.5 11.38
1 947714 951356 110.99
1 1404923 1410311 96.76 27.04
<强>阐释:强>
-a
选项将行拆分为字段。 -l
选项为我们选择并在打印期间放回新行-n
选项对文件的每一行执行-e
选项告诉perl执行代码块$k = "@F[0..2]"
创建一个变量$k
,其中包含当前行的前三个字段push @o, $k if !$h{$k}
只有在我们的哈希中不存在时才会创建一个数组并将变量推送给它。这是为了防止插入重复。这也是为了我们可以保留订单push @{$h{$k}}, $F[3]
我们正在创建数组哈希。使用键作为$k
并将值作为最后一个字段推送到哈希。 }{
表示END
块print "$_ @{$h{$_}}" for @o
打印数组@o
的每个元素的键和值。 以下是更易读的单行内容:
perl -lane '{
$k = "@F[0..2]";
push @o, $k if !$h{$k};
push @{$h{$k}}, $F[3]
}
END {
print "$_ @{$h{$_}}" for @o
}' file