我有一个制表符分隔文件(每行中的列数不固定),如下所示:
chr1 92536437 92537640 NM_024813 NM_053274
我希望按照以下顺序从中获取一个文件(前三列是分割时需要的标识符)
chr1 92536437 92537640 NM_024813
chr1 92536437 92537640 NM_053274
有关shell脚本的建议。
答案 0 :(得分:4)
#!/bin/bash
{
IFS=' '
while read a b c rest
do
for fld in $rest
do
echo -e "$a\t$b\t$c\t$fld"
done
done
}
请注意,您应该在那里输入一个真实标签(IFS
)
我还以为我应该做一个perl版本:
#!/bin/perl -n
($a,$b,$c,@r)=(chomp and split /\t/); print "$a\t$b\t$c\t$_\n" for @r
从命令行执行所有操作,从in.txt读取并输出到out.txt:
perl -ne '($a,$b,$c,@r)=(chomp and split /\t/); print "$a\t$b\t$c\t$_\n" for @r' in.txt > out.txt
当然如果你保存perl脚本(比如script.pl)
perl script.pl in.txt > out.txt
如果您还使脚本文件可执行(chmod +x script.pl
):
./script.pl in.txt > out.txt
HTH
答案 1 :(得分:3)
不是shell,另一个答案非常好,但我在perl中使用了它:
perl -F'/\s/' -lane '$,="\t"; print @F,$_ for splice @F,3' $FILE
修改:新版(更难以理解;)版本,受其他答案的启发。滥用perl的命令行参数和特殊变量进行自动分割和行结束处理。
意味着:对于前三个(for splice @F,3
)之后的每个字段,打印前三个字段(print @F,$_
)。
-F
将字段分隔符设置为\s
(应为\t
)-a
自动分割为@F
。
-l
启用-n
的行结束处理,为每行输入运行-e
代码。
$,
是输出字段分隔符。
答案 2 :(得分:1)
[被修改]
所以你想复制每个剩余项目的前三列吗?
$ cat File | while read X
do PRE=$(echo "$X" | cut -f1-3 -d ' ')
for Y in $(echo "$X" | cut -f4- -d ' ')
do echo $PRE $Y >> OutputFilename
done
done
返回:
chr 786 789 NM
chr 786 789 NR
chr 786 789 NT
chr 123 345 NR
这会将前三个以空格分隔的列作为前缀切割,然后滥用for循环将逐步通过空格分隔列表来调用echo的事实。
享受。
答案 3 :(得分:0)
这只是您data comparison in two files问题的一部分。
从那里提取我稍微讨厌的解决方案:
for i in 4 5 6 7; do join -e _ -j $i f f -o 1.1,1.2,1.3,0; done | sed '/_$/d'