我有数据文件,如下所示:
chr1 762440 762981 SAMD11
chr1 858932 859148 KLHL17 SAMD11 NOC2L
chr1 859786 860145 KLHL17 SAMD11 NOC2L
chr1 890663 891747 KLHL17 NOC2L SAMD11 HES4 我想用前三列中的值排列所有的名字--一个在另一个下面。
就像这样
chr1 762440 762981 SAMD11
chr1 858932 859148 KLHL17
chr1 858932 859148 SAMD11
chr1 858932 859148 NOC2L
chr1 859786 860145 KLHL17
chr1 859786 860145 SAMD11
chr1 859786 860145 NOC2L这个输出用于前三行,但对于整个集合来说是需要的。
每行的名字数不是固定的,请记住这一点(可以是1、5、10或20个名字)。
What I thought使用sed -i .bak将名称放在另一列下,并将值放在前三列中。
但最终它变得过于复杂了。
你能想出一个简单的方法来绕过这件事吗?
谢谢
发布于 2013-11-28 10:04:51
使用awk
awk '{for (i=4;i<=NF;i++) print $1,$2,$3,$i}' file
chr1 762440 762981 SAMD11
chr1 858932 859148 KLHL17
chr1 858932 859148 SAMD11
chr1 858932 859148 NOC2L
chr1 859786 860145 KLHL17
chr1 859786 860145 SAMD11
chr1 859786 860145 NOC2L
chr1 890663 891747 KLHL17
chr1 890663 891747 NOC2L
chr1 890663 891747 SAMD11
chr1 890663 891747 HES4发布于 2013-11-28 12:27:55
下面是我如何在Perl中这样做的:
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
while (<DATA>) {
chomp;
my @line = split;
for my $field (@line[3 .. $#line]) {
say "@line[0 .. 2] $field";
}
}
__END__
chr1 762440 762981 SAMD11
chr1 858932 859148 KLHL17 SAMD11 NOC2L
chr1 859786 860145 KLHL17 SAMD11 NOC2L
chr1 890663 891747 KLHL17 NOC2L SAMD11 HES4 发布于 2013-11-28 10:05:51
在bash (100%内部命令)中,我得到了以下答案:
#!/bin/bash
while read ONE TWO THREE FOUR
do
for ARG in $FOUR
do
if [ ${ARG:0:1} != "(" ] #<-- filtering out args with parentheses
then
echo "$ONE $TWO $THREE $ARG"
fi
done
done <"/path/to/your/datafile"但是,由于您更改了问题,这也会将答案更改为:
#!/bin/bash
while read ONE TWO THREE FOUR
do
for ARG in $FOUR
do
echo "$ONE $TWO $THREE $ARG"
done
done <"/path/to/your/datafile"https://stackoverflow.com/questions/20262673
复制相似问题