Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用IDs阵列的单zcat多提取_Python_Bash_Zcat - Fatal编程技术网

Python 使用IDs阵列的单zcat多提取

Python 使用IDs阵列的单zcat多提取,python,bash,zcat,Python,Bash,Zcat,我有很多GB+大小的gz档案,由于磁盘空间的原因,我无法解压缩。每个归档文件都有一个特定的标识号(例如test365.gz)和如下结构: 1 1 2 1 ########## Name: ZINC000077407198 @<TRIPOS>MOLECULE ZINC000077407198 none @<TRIPOS>ATOM 1 C1 5.7064 -2

我有很多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
目前我有:

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
姓名:ZINC00077407100
@分子
ZINC00077407100无
@原子
1 C1 1.4756-2.2562-14.0852 C.3 1 LIG1-0.1500
@债券
1    1    2 1
##########姓名:ZINC00077407198
这很好用。如果ZINC00077407100有N个块,我将在zcat上提取N个块,不介意以#####开始的行

问题是我需要读取归档文件N次,以获取我想要的信息的N个标识符/锌编号。这需要很多时间,因为我有成千上万的东西要提取

因此,我想找到一种方法来传递一个数组或标识符列表/zin_NUMBER,以根据数组/列表中的标识符将zcat读取输出到几个不同的文件

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


谢谢你的帮助

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

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

为了防止误报(可能会加快搜索速度),我们只搜索完整的行,而不是子字符串。为了加快速度,我们设置了
LC\u ALL=C
。您还可能发现
zgrep
zcat | grep
更快

下面的脚本最多对每个归档文件解压缩一次

awk -v prefix='##########                 Name:     ' '
  {a[$1]=a[$1] "\n" prefix $2}
  END {for (k in a) print k a[k] "\0"}
' /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

每个操作都需要处理大量数据(数百万行、多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
#/bin/bash-uex
TAGS=data.txt
文件列表=$(awk'{print$1}'<$TAGS | sort-u)
对于$file\u列表中的f;
做
gz_name=${f%/}.gz
zcat$gz|u name | awk-v F=$F'
#记住要检索的标记
!数据&&$1==F{tags[$2]=1}
#设置为当前输出文件,如果未选择项,则为空
数据&&$1==“&$2==”姓名:{
OUT=标签[$3]?$3“.OUT”:“;
}
输出{打印>输出}
“$TAGS DATA=1-
完成

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

您的问题很难理解。我看到
test365.gz
是一个GB+文件。问题是您希望在该文件中查找数百个文本块,并将每个文本块输出到不同的文件?或者您想在数百个其他文件中搜索数百个文本块,每个文件的大小都与
test365.gz
一样大?还是别的什么?顺便说一下,使用
sed
搜索IMHO很少是解决方案,我怀疑
awk
可能更好。您确定此处发布的
sed
命令对您有效吗?首先,我希望使用
-n
选项,正如您所说,您无法解压缩整个文件。然后sed命令有for
s/a/,/b/p
,这会为我抛出一个错误。您的意思是
sed-n'/a/,/b/p'
?您是否试图将大文件拆分为多个由ID键入的小文件(例如Zinc00077407100.out)。您是需要每个ID的文件,还是需要一个小子集的文件(将检索多少ID,而文件中有多少ID)?此外,“sed”命令将复制文件的所有内容,包括不包含模式的行。这将比原来占用更多的空间。最后一条评论:请澄清行尾在哪里(输入似乎环绕)。谢谢破折号。这是可怕的,使它完美!您将为我节省大量的处理时间,并有望有助于更有效地发现类似于LSD、psilocin或其他类似分子的新药:)。如果你觉得很有创意,想用python(我使用++)或perl(我有时使用)或其他任何东西来提出建议,请随意!谢谢你的考虑,所以我会记住的。然而,我只是用一种愚蠢的方式缩短了输入,并没有看到它由6行组成的块:)。每个块的行数是可变的。与为
grep
生成模式类似,您可以为
sed
生成
/…/,/…/p
-模式。但是,由于您已经接受了答案,因此无需:)
zgrep ... > /tmp/zincfound
while IFS= read -r pattern; do
    grep -A6 -Fx "$pattern" /tmp/zincfound > "${pattern##* }.out" 
done <<< "$patterns"
rm /tmp/zincfound
#! /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