我有一个文件,其间隔从“开始”列开始,到“结束”列结束。我必须根据第四列中写入的定义长度提取这些间隔的开始和结束。我还必须打印“分数”列中存在的信息。该文件如下所示:
Input:
chr start end score length
chr1 237592 237601 176 320
chr1 237601 237912 176 320
chr1 521409 521601 150 320
chr1 521601 521729 150 320
chr1 714026 714346 83 320
chr1 805100 805201 323 340
chr1 805201 805440 323 340
Output:
chr start end score length
chr1 237592 237912 176 320
chr1 521409 521729 150 320
chr1 714026 714346 83 320
chr1 805100 805440 323 340
正如您注意到的,要提取的间隔长度位于第五列。例如输出中间隔的长度:
chr1 237592 237912
已通过将 237912(在“结束”列的第二行中)减去 237592(在“开始”列的第一行中)得到,即 320(如第 5 列中所定义)。
任何想法都非常感激。
答案1
松散地说,问题在于合并线。如果一条线的起始坐标与上一行的结束坐标相同,则该线可以与前一行“合并”。
这些线可能对应于基因组特征。目的是合并基因组序列中相邻的特征。
这是一个awk
执行此操作的脚本:
$2 == end {
# This line merges with the previous line.
# Update end and continue with next line.
end = $3;
next;
}
{
# This is an unmergeable line (start doesn't correspond to end on
# previous line).
# If we've processed at least the header line, print the data collected.
# The if statement avoids printing an empty output line at the
# start of the output.
if (NR > 1) {
print chr, start, end, score, len;
}
# Get data from this line.
chr = $1;
start = $2;
end = $3;
score = $4;
len = $5;
}
END {
# At the end of input, print the data as above to output last line.
print chr, start, end, score, len;
}
该脚本假设输入已排序,并且所有起始坐标都严格小于结束坐标(即所有特征都位于正链上)。
测试它:
$ awk -f script.awk data
chr start end score length
chr1 237592 237912 176 320
chr1 521409 521729 150 320
chr1 714026 714346 83 320
chr1 805100 805440 323 340
答案2
对我来说,这看起来像一个文本文件,其中的列由空格分隔。它可以被优雅地处理,R
但 shell 脚本也可以做到这一点。您需要的是使用循环逐行读取文件for
。在循环中,一种简单的方法是将每个列值(您可以用于cut
该值)分配给一个变量,然后按照您想要的顺序打印变量。第二列和第五列变量加在一起生成输出的第三列。您可以使用echo
for 循环在屏幕上打印每条输出行。当您看到屏幕上打印出您喜欢的行时,您只需将脚本的输出重定向到类似的文件your_script.sh > your new output.txt