我需要对文件进行排序, mwe.txt :
>gb|LOEQ01000001.1|
1 CC|1 CC|1 NN|0 NN|0 NN|0 CC|1 NN|0 CC|1 CC|1 CC|1
2 AA|1 AA|1 NN|0 NN|0 NN|0 AA|1 NN|0 AA|1 AA|1 AA|1
>gb|LOEQ01000181.1|
1 CC|1 CC|1 NN|0 NN|0 NN|0 CC|1 NN|0 CC|1 CC|1 CC|1
>gb|LOEQ01000131.1|
1 CC|1 CC|1 NN|0 NN|0 NN|0 CC|1 NN|0 CC|1 CC|1 CC|1
2 AA|1 AA|1 NN|0 NN|0 NN|0 AA|1 NN|0 AA|1 AA|1 AA|1
3 AA|1 AA|1 NN|0 NN|0 NN|0 AA|1 NN|0 AA|1 AA|1 AA|1
names.txt 中的示例标识符:
LOEQ01000001.1
LOEQ01000131.1
LOEQ01000181.1
我已经用sed和awk实现了这个目标:
for f in $(cat names.txt); do sed -n -e "/$f|/,/>/ p" mwe.txt | awk '/>/&&c++>0 {next} 1' >> sorted.txt; done
结果是:
>gb|LOEQ01000001.1|
1 CC|1 CC|1 NN|0 NN|0 NN|0 CC|1 NN|0 CC|1 CC|1 CC|1
2 AA|1 AA|1 NN|0 NN|0 NN|0 AA|1 NN|0 AA|1 AA|1 AA|1
>gb|LOEQ01000131.1|
1 CC|1 CC|1 NN|0 NN|0 NN|0 CC|1 NN|0 CC|1 CC|1 CC|1
2 AA|1 AA|1 NN|0 NN|0 NN|0 AA|1 NN|0 AA|1 AA|1 AA|1
3 AA|1 AA|1 NN|0 NN|0 NN|0 AA|1 NN|0 AA|1 AA|1 AA|1
>gb|LOEQ01000181.1|
1 CC|1 CC|1 NN|0 NN|0 NN|0 CC|1 NN|0 CC|1 CC|1 CC|1
我使用的实际文件大于120gb,我的解决方案效率非常低。我想可以使用递归合并排序算法,但我不确定如何组织输入数据以便对其进行排序,主要是因为每个样本/标识符的行数不一致。任何人都可以建议更快的方式吗?
答案 0 :(得分:4)
$ cat tst.awk
BEGIN { FS="|" }
NR==FNR { keys[++numKeys] = $0; next }
/^>/ { key = $2 }
{ block[key] = block[key] $0 ORS }
END {
for (keyNr=1; keyNr<=numKeys; keyNr++) {
key = keys[keyNr]
printf "%s", block[key]
}
}
$ awk -f tst.awk names.txt mwe.txt
>gb|LOEQ01000001.1|
1 CC|1 CC|1 NN|0 NN|0 NN|0 CC|1 NN|0 CC|1 CC|1 CC|1
2 AA|1 AA|1 NN|0 NN|0 NN|0 AA|1 NN|0 AA|1 AA|1 AA|1
>gb|LOEQ01000131.1|
1 CC|1 CC|1 NN|0 NN|0 NN|0 CC|1 NN|0 CC|1 CC|1 CC|1
2 AA|1 AA|1 NN|0 NN|0 NN|0 AA|1 NN|0 AA|1 AA|1 AA|1
3 AA|1 AA|1 NN|0 NN|0 NN|0 AA|1 NN|0 AA|1 AA|1 AA|1
>gb|LOEQ01000181.1|
1 CC|1 CC|1 NN|0 NN|0 NN|0 CC|1 NN|0 CC|1 CC|1 CC|1
这会更快,但它确实意味着你需要将整个文件存储在内存中,所以试试看看是否存在问题。如果是,那么您可以一次获取一些键名称,并使用类似这样的脚本:
$ cat tst.awk
BEGIN { FS="|" }
NR==FNR { keys[++numKeys] = $0; tgtKeys[$0]; next }
/^>/ { key = $2 }
key in tgtKeys { block[key] = block[key] $0 ORS }
END {
for (keyNr=1; keyNr<=numKeys; keyNr++) {
key = keys[keyNr]
printf "%s", block[key]
}
}
< names.txt xargs -n 1000 echo | awk -f tst.awk - mwe.txt
将一次打印mwe.txt 1000行。