我正在尝试找到一个更快(最有效)的工具来搜索非常大的~100GB file2
。搜索的输入是file1
,它只是列中#'s
的列表(每行1个)---可能有几百---。 File2
是特定格式的ID的排序列表,其中#file1
与$2
中的file2
值匹配。我尝试了各种grep
,awk
和ack
命令,但它们似乎都有用,但也许有更好的方法。下面的命令似乎有点帮助但是因为可能有很多#s来查找它可能不是最好的方法。谢谢 :)。下面的每一个都在大约40分钟内完成,而file1
只有2行,它通常有100行。谢谢:)。
<file2 sed -e 's/^/(^|,)/' -e 's/$/($|,)/' | grep -E -f - file1 > out
awk
BEGIN { FS=OFS="\t" }
NR==FNR {
c = ++num[$1]
beg[$1][c] = $1
val[$1][c] = $NF
next
}
$2 in val {
for (c=1; c<=num[$1]; c++) {
if ( (beg[$1][c] = $2) ) {
print $0, val[$1][c]
break
}
}
}
文件1
2307492
7349185
file2 tab-delimited
NC_000001.10:g.26131654G>A 7349185
NC_000001.11:g.25805163G>A 7349185
XM_006715659.1:c.1454-13758T>C 22
XM_006715660.1:c.1454-13758T>C 22
XR_921761.2:n.662T>C 2307492
XR_922278.2:n.1307-31218A>G 2307492
所需的输出
NC_000001.10:g.26131654G>A 7349185
NC_000001.11:g.25805163G>A 7349185
XR_921761.2:n.662T>C 2307492
XR_922278.2:n.1307-31218A>G 2307492
答案 0 :(得分:2)
如果您想确保file1
中的数字专门位于file2
的最后一列,您可以将sed
与生成的命令文件一起使用:
首先使用sed
或awk
生成命令文件:
$ awk '{printf "/\t%s$/p\n", $1}' file1
/ 2307492$/p
/ 7349185$/p
然后将其提供给sed
以处理文件2:
$ sed -n -f <(awk '{printf "/\t%s$/p\n", $1}' file1) file2
NC_000001.10:g.26131654G>A 7349185
NC_000001.11:g.25805163G>A 7349185
XR_921761.2:n.662T>C 2307492
XR_922278.2:n.1307-31218A>G 2307492
如果只打印file1
行file2
中的某个数字,则可以使用grep
:
$ grep -wFf file1 file2
NC_000001.10:g.26131654G>A 7349185
NC_000001.11:g.25805163G>A 7349185
XR_921761.2:n.662T>C 2307492
XR_922278.2:n.1307-31218A>G 2307492
或者,使用awk
,您可能会读取文件1中的数字,拆分为\t
并测试文件2的第2列:
$ awk -F"\t" 'FNR==NR{fi[$1]; next}
$2 in fi' file1 file2
NC_000001.10:g.26131654G>A 7349185
NC_000001.11:g.25805163G>A 7349185
XR_921761.2:n.662T>C 2307492
XR_922278.2:n.1307-31218A>G 2307492
任何这些(我认为)都会像你没有数据库那样快。
答案 1 :(得分:1)
不确定它是否会比你尝试的更快,但我想到的是:
在正则表达式中转换file1
以传递给awk
,并在解析file2
的每一行时应用正则表达式:
awk -F"\t" -v regex=`awk '{printf "%s|",$0} END{printf "\b"}' file1` '$2~regex{print $0}' file2
详细信息:
awk '{printf "%s|",$0} END{printf "\b"}'
将转换:
2307492
7349185
收件人:2307492|7349185
由于之前的正则表达式存储在regex
变量中:
'$2~regex{print $0}'
表示:'$2~/2307492|7349185/{print $0}'
即:如果$2
与正则表达式匹配,则打印该行
答案 2 :(得分:1)
尝试:
awk 'FNR==NR{a[$0];next}($NF in a)' file1 file2
所以在这里检查一个条件FNR == NR当第一个文件被读取时它将为TRUE(在这种情况下为file1)。然后创建名为a的数组,其索引为$ 0(仅在file1中为当前行),使用next将停止游标进一步运行,以便不再执行所有其他命令。 现在提到条件检查是否$ NF(file2的最后一个字段)存在于数组a中,如果是,则打印file2的当前行(awk工作条件然后是action方法,因此如果条件为TRUE则应该发生某些操作,因此在此case没有提到动作所以默认情况下会发生打印当前行的文件2)。