单个 zcat 具有 ID 数组的多个数据提取



我有很多GB+大小的gz存档,由于磁盘空间原因我无法解压缩。每个存档都有一个特定的标识号(例如 test365.gz(和如下结构:

1    1    2 1
##########                 Name:     ZINC000077407198
@<TRIPOS>MOLECULE
ZINC000077407198      none
@<TRIPOS>ATOM
1 C1          5.7064    -2.3998   -12.0246 C.3        1  LIG1  -0.1500
@<TRIPOS>BOND
1    1    2 1
##########                 Name:     ZINC000099999999
@<TRIPOS>MOLECULE
ZINC000099999999      none
@<TRIPOS>ATOM
1 C1         -2.0084    -5.2055   -12.9609 C.3        1  LIG1  -0.1500
@<TRIPOS>BOND
1    1    2 1
##########                 Name:     ZINC000077402345
@<TRIPOS>MOLECULE
ZINC000077402345     none
@<TRIPOS>ATOM
1 C1          6.5657    -1.5531   -15.3414 C.3        1  LIG1  -0.1500
@<TRIPOS>BOND
1    1    2 1
##########                 Name:     ZINC000077407198
@<TRIPOS>MOLECULE
ZINC000077407198      none
@<TRIPOS>ATOM
1 C1          3.6696    -1.8305   -14.6766 C.3        1  LIG1  -0.1500
@<TRIPOS>BOND
1    1    2 1
##########                 Name:     ZINC000012345678
@<TRIPOS>MOLECULE
ZINC000012345678      none
@<TRIPOS>ATOM
1 C1          4.5368    -0.8182   -17.4314 C.3        1  LIG1  -0.1500
@<TRIPOS>BOND
1    1    2 1
##########                 Name:     ZINC000077407100
@<TRIPOS>MOLECULE
ZINC000077407100      none
@<TRIPOS>ATOM
1 C1          1.4756    -2.2562   -14.0852 C.3        1  LIG1  -0.1500
@<TRIPOS>BOND
1    1    2 1
##########                 Name:     ZINC000077407198
@<TRIPOS>MOLECULE
ZINC000077407198      none
@<TRIPOS>ATOM
1 C1          6.1712    -0.8991   -16.4096 C.3        1  LIG1  -0.1500
@<TRIPOS>BOND
1    1    2 1
##########                 Name:     ZINC000077407198
@<TRIPOS>MOLECULE
ZINC000077407198      none
@<TRIPOS>ATOM

### 定义的块之间的行数是可变的。

我有一个锌实体 + 目标存档的标识符列表:

test365/    ZINC000077407198
test227/    ZINC000009100000
test365/    ZINC000077407100
... 

目前我做:

zcat test365.gz | sed -n '/##########                 Name:     ZINC000077407100/,/##########                 Name:/p' > ZINC000077407100.out

我得到:

##########                 Name:     ZINC000077407100
@<TRIPOS>MOLECULE
ZINC000077407100      none
@<TRIPOS>ATOM
1 C1          1.4756    -2.2562   -14.0852 C.3        1  LIG1  -0.1500
@<TRIPOS>BOND
1    1    2 1
##########                 Name:     ZINC000077407198

哪个工作正常。如果有 N 个块用于ZINC000077407100我在 zcat 上提取 N 个块,并且不介意以 ##### 开头的行。

问题是我需要读取 N 次存档以获取我想要信息的 N 个标识符/ZINC_NUMBER。而且由于我有数千个要提取,因此需要花费很多时间。

所以我想找到一种方法来传递一个数组或标识符列表/ZINC_NUMBER,以将 zcat 读数输出到几个不同的文件,以函数数组/列表中的标识符。

换句话说,我想使用 zcat 进行单次读取,并为一组标识符提取数据,而不仅仅是一个标识符。

感谢您的帮助!

每个 OP 的要求是处理大量数据(数百万行、数 GB 数据以及检索大约 100 个项目的数据(。从技术上讲,现代 bash 是可行的,但这不太可能表现良好。更好的脚本引擎在这里会做得更好。

这里提供了可能的 bash/awk 解决方案。它将扫描每个引用的文件一次,并通过一次传递提取所有选定的标签。请注意,"标签"列表将被多次扫描,但暗示它的大小是合理的

#! /bin/bash -uex
TAGS=data.txt
file_list=$(awk '{ print $1 }' < $TAGS | sort -u)
for f in $file_list ;
do
gz_name=${f%/}.gz
zcat $gz_name | awk -v F=$f '
# Remember tags to retrieve
!DATA && $1 == F { tags[$2] = 1 }
# OUT set to current output file, empty if item not selected
DATA && $1 == "##########" && $2 == "Name:" {
OUT = tags[$3] ? $3 ".out" : "" ;
}
OUT { print >OUT }
' $TAGS DATA=1 -
done

不用说,可以使用Python,Perl,Javascript或您喜欢的文本处理工具编写上述5行awk作业。使用示例数据集进行测试。

>似乎每个以##########开头的条目总是有 6 行。在这种情况下,使用grep -A7而不是sed -n /##.../,/##.../p会更容易、更有效。我想您只打印了后续标题,因为这样更容易(至少在使用sed时(。因此,我在此答案中排除了后续标题(grep -A6而不是grep -A7(。

可以grep给出要搜索的模式列表。这是通过-f选项完成的。可以从您的文件生成模式列表。按存档名称排列的第一组(例如test365(,然后打印该存档的所有模式。在这里,我们使用awk来做到这一点。空字节分隔每个存档的模式部分。

为了防止误报(并可能加快搜索速度(,我们只搜索完整的行而不是子字符串。为了加快速度,我们设置了LC_ALL=C。您可能还会发现zgrepzcat | grep快。

以下脚本最多解压缩每个存档一次。

awk -v prefix='##########                 Name:     ' '
{a[$1]=a[$1] "n" prefix $2}
END {for (k in a) print k a[k] ""}
' /path/to/your/list.txt |
while IFS=$'n' read -r -d '' archive patterns; do
LC_ALL=C zgrep -A6 -Fxf <(printf %s "$patterns") "${archive///.gz}"
# TODO do something with the output for this archive
done

在上面的脚本中,我将自动将列表中的test365/转换为test365.gz。我不知道你的目录结构。如果您需要不同的东西,请改编zgrep的最后一个参数。$archive循环访问(分组(列表的第一列(即,每个存档仅列出一次(。

从示例代码来看,您似乎希望为每个模式生成一个单独的文件。为此,请将环体从上方更换至

zgrep ... > /tmp/zincfound
while IFS= read -r pattern; do
grep -A6 -Fx "$pattern" /tmp/zincfound > "${pattern##* }.out" 
done <<< "$patterns"
rm /tmp/zincfound

相关内容

  • 没有找到相关文章

最新更新