for 循环中“参数列表太长”

for 循环中“参数列表太长”

我的 shell 脚本如下所示:

#!/bin/bash

for file in *.fasta
do

signalp $file > $file.txt

done

在工作文件夹中,我有 18.000 个 .fasta 文件。我想通过 signalp 程序运行每个程序。我猜文件夹中的文件太多,但我不知道如何调整我的代码。有什么帮助吗?

答案1

您可以使用find

find . -maxdepth 1 -type f -exec sh -c 'signalp "$1" >"$1".txt' _ {} \;
  • -maxdepth 1只会在当前目录中find搜索文件 ( )-type f

  • sh -c 'signalp "$1" >"$1".txt'signalp将对找到的所有文件执行该命令,并将输出保存到添加.txt到原始文件名后命名的文件中。

答案2

你会得到一个argument list too long错误是因为你没有引用你的论点。正在发生扩张——尽管很难确定什么$file它是 -其产生的价值更多论点。我的理论是您的一个文件名包含另一个文件名,*该文件名再次扩展以再次匹配所有匹配的文件。

在 shell 中执行此操作 - 并且您不需要调用整个新的shell viafind也可以做到这一点。

只需这样做:

for f in ./*.fasta
do  signalp "$f" >"$f.txt"
done

...看?双引号将阻止可迭代 shell 变量的内容$f以除字面意义外的任何方式进行解释 - 即使确实$f包含可扩展的元字符。

不过,诚然,这是不是18k 文件组的最佳解决方案。它将要工作,但如果你能批处理它会更好更远

举个例子,我们假设有某种命令文件名本身。也许他们的名字是这样的...

aaa001.fasta
...
bbb001.fasta

等等。在这种情况下你可以这样做:

for l in a b c d e f g h i j k l m n o p q r s t u v x y z
do    for  f in "./$l$l$l"*.fasta
      do   singalp "$f" >"$f.txt"
done; done

...因此您不需要在循环期间将整个 18k 列表保留在内存中。

相关内容