/bin/ls:参数列表太长

/bin/ls:参数列表太长

我是一名生物学家,正在运行一个名为 autodock 的程序。我有一些来自 ZINC 库的 .mol2 格式的文件。根据要求,我需要使用命令拆分此文件csplit,并且我收到了目录中的所有内容。父文件被分成非常非常多的小文件。每个文件名都是这样的:ZINC14382748.mol2.现在我必须将所有这些文件更改为 pdbqt 格式,并且必须使用以下脚本:

#!/bin/csh # # $Id: ex02.csh,v 1.5 2007/07/19 21:52:59 rhuey Exp $ 
# 
# use the 'prepare_ligands.py' python script to create pdbq files 
cd $VSTROOT/VirtualScreening/Ligands 
foreach f (`ls *`) echo $f pythonsh ../../prepare_ligand4.py -l $f -d ../etc/ligand_dict.py end 

当我使用它时,它说

/bin/ls: Argument list too long

简而言之,成功完成后,它将把上述数量的文件复制为另一种格式。那么有没有什么合理的办法来解决这个问题呢?

答案1

  1. 不要解析 的输出ls  说啊foreach f (*)。还,
  2. 您应该始终引用您的 shell 变量引用(例如,"$f"),除非您有充分的理由不这样做,并且您确定您知道自己在做什么。

答案2

问题的根源在于您有太多的小文件。

如果我没看错的话,你有超过 14 个百万文件。任何 shell 都不可能在命令行上拥有超过 1400 万个文件名。除此之外。您的文件名长度似乎约为 18 个字符,因此大约需要 18*14M 或大约 252 MB 来保存文件名。

bash例如,有 128KB 的限制。比 252MB 略小。我不知道csh有什么限制,因为我不使用它。它不太可能大于 bash 的命令行长度限制。它肯定不会是 252MB 或更大。

不过,一切并没有丢失,你find ... -exec还可以使用。

find . -maxdepth 1 -type f -name '*.mol2' \
  -exec pythonsh ../../prepare_ligand4.py -l {} -d ../etc/ligand_dict.py \;

这将为prepare_ligand4.py每个文件运行一次,因此需要非常很久。通过使用find ... -print0withxargs -0 -P ...或 GNUparallel -0 ...而不是find ... -exec


一个更好的解决方案是下载源代码prepare_ligand4.py并修改它,以便您可以给它一个大文件(例如csplit-ing 之前的原始文件),并且它将单独处理每个块。这将是很多更快、更容易使用。您可能仍然拥有超过 14M 的输出文件(假设合并的输出文件将毫无用处......如果不是的话,那么您很幸运!),但这比拥有 14M 输入文件和 14M 输出文件要好。

当然,这需要一些python编程技巧。

也许有人已经遇到了同样的问题并编写了自己的增强版本prepare_ligand4.py。值得花一些时间搜索,或者尝试一下Autodock 论坛甚至联系 Autodock 作者。

答案3

显然你有很多文件。考虑使用 GNU Parallelhttp://www.gnu.org/software/parallel/“ls -U”不对文件进行排序,因此速度更快。

cd $VSTROOT/VirtualScreening/Ligands
ls -U ZINC* | parallel echo {} \; pythonsh ../../prepare_ligand4.py -l {} -d ../etc/ligand_dict.py

我不明白你为什么要回应它。您会将其解析为新脚本吗?我的猜测是“prepare_ligand4.py”是转换脚本,然后这应该可以完成工作(并行):

cd $VSTROOT/VirtualScreening/Ligands
ls -U ZINC* | parallel pythonsh ../../prepare_ligand4.py -l {} -d ../etc/ligand_dict.py

答案4

我已经解决了这个问题,分享给大家。我将 bash.csh 重命名为 bash.sh,接下来我更改脚本以便在 bash 中运行它。这是我的新脚本,可以帮助将来解决同样的问题。

#!/bin/bash
cd $VSTROOT/VirtualScreening/Ligands/
for f in ZINC*.mol2
do
    echo "$f"
    pythonsh ../../prepare_ligand4.py -l "$f" -d ../etc/ligand_dict.py
done

对于像我这样的初学者来说,这里的 ZINC 是所有配体名称中存在的名称的一部分,因此必须根据您的配体名称保留。感谢您的时间和我的朋友热情地帮助我。

相关内容