我有2个文件;让我们称他们为file1和file2。File1在每一行中包含一个开始和结束坐标,例如:
start end
2000 2696
3465 3688
8904 9546
等。
file2有几列,其中第一个与问题最相关:
position v2 v3 v4
3546 value12 value13 value14
9847 value22 value23 value24
12000 value32 value33 value34
现在,我需要输出一个新文件,该文件仅包含"位置"值(第一列)在任何列的"启动"one_answers"端"值之间的file2行(第一列)文件1。在r中,我只需进行双循环,但是需要太多时间(文件很大),因此需要在bash中进行。如果问题不清楚,这是可以完成工作的R循环:
for(i in 1:dim(file1)[1]){
for(j in 1:dim(file2)[1]){
if(file2[j,1]>file1$start[i] & file2[j,1]<file1$end[i]) file2$select=1 else file2$select=0
}
}
非常确定有一种简单的方法可以使用bash/awk ...
尴尬看起来像这样,但是您需要先从file1和file2删除第一行:
:awk 'FNR==NR{x[i]=$1;y[i++]=$2;next}{for(j=0;j<i;j++){if($1>=x[j]&&$1<=y[j]){print $0}}}' file1 file2
" fnr == nr"之后的卷曲括号中的位仅适用于file1的处理,它说将field1存储在数组x []中,而field2则在数组y []中,因此我们具有每个的上限和下限范围。第二组卷发括号中的位仅适用于proding file2。它在数组x []和y []中的所有界限中迭代,然后查看field1是否在边界之间,并在整个重新分配之间打印。
。如果您不想在开始时删除标题线,则可以使尴尬更加复杂,并像这样忽略它:
awk 'FNR==1{next}FNR==NR{x[i]=$1;y[i++]=$2;next}{for(j=0;j<i;j++){if($1>=x[j]&&$1<=y[j]){print $0}}}' file1 file2
编辑
好吧,我添加了代码以检查"染色体"(无论是什么!),假设它在两个文件中的第一个字段中,都这样:
file1
x 2000 2696
x 3465 3688
x 8904 9546
file2
x 3546 value12 value13 value14
y 3467 value12 value13 value14
x 9847 value22 value23 value24
x 12000 value32 value33 value34
因此,该代码现在也将染色体存储在阵列C []中,并在输出之前检查它们是相等的。
awk 'BEGIN{i=0}FNR==NR{c[i]=$1;x[i]=$2;y[i++]=$3;next}{for(j=0;j<i;j++){if(c[j]==$1&&$2>=x[j]&&$2<=y[j]){print $0;next}}}' file1 file2
不知道如何在bash中做到这一点...
我会尝试一个perl脚本,读取第一个文件并将其存储在内存中(如果可能的话,取决于其大小),然后按行浏览第二个文件,然后进行比较以输出线路是否输出线路。
我认为您也可以以r为...相同的方式:存储第一个文件,为第二个文件的每一行循环循环。
此外,如果间隔不重叠,则可以在文件上进行排序以加快算法。
这应该比 for
loop
res <- apply(file2, 1, function(row)
{
any(row$position > file1$start & row$position < file1$end)
})
假设文件的定界符是空格(如果不是 - 更改-d估算)。
脚本使用cut
提取文件2的第一个字段。然后,简单的GREP搜索File1中的字段。如果存在,则打印了File2的行。
#!/bin/bash
while read line
do
word=$(echo $line | cut -f1 -d" ")
grep -c $word file1 >/dev/null
if [ $? -eq 0 ];then
echo "$line"
fi
done < file2