一个bash脚本,用于为没有特定文件的目录运行程序

时间:2012-08-13 10:03:17

标签: linux shell exec

我需要一个Bash脚本为所有没有特定文件的目录执行程序,并在同一目录下创建输出文件。该程序需要一个输入文件,该文件存在于名称为 *的每个目录中.DNA.fasta .Suppose我有以下目录,也可能包含子目录

dir1/a.protein.fasta  
dir2/b.protein.fasta  
dir3/anyfile  
dir4/x.orf.fasta

我首先找到的目录没有那个名称为 *。的特定文件。蛋白质。快速
在这种情况下,我希望列出dir3dir4(因为它们不包含*.protein.fasta) 我试过这段代码:

find . -maxdepth 1  -type d  \! -exec test -e '{}/*protein.fasta' \; -print

但似乎我错过了一些不起作用的东西。 我也不知道如何处理整个故事。

2 个答案:

答案 0 :(得分:2)

这是一个棘手的问题。

我想不出好的解决方案。但是,这是一个解决方案。请注意,如果您的目录或文件名包含换行符,则保证不可以正常工作,如果它们包含其他特殊字符,则无法保证可以正常工作。 (我只测试了你问题中的样本。)

此外,我还没有添加-maxdepth,因为您说您也需要搜索子目录。

#!/bin/bash

# Create an associative array
declare -A excludes

# Build an associative array of directories containing the file
while read line; do
  excludes[$(dirname "$line")]=1
  echo "excluded: $(dirname "$line")" >&2
done <<EOT
$(find . -name "*protein.fasta" -print)
EOT

# Walk through all directories, print only those not in array
find . -type d \
| while read line ; do
  if [[ ! ${excludes[$line]} ]]; then
    echo "$line"
  fi
done

对我来说,这会返回:

.
./dir3
./dir4

所有这些目录都不包含与*.protein.fasta匹配的文件。当然,您可以将最后echo "$line"替换为您对这些目录所需的任何内容。

<强>可替换地:

如果你真正想要的只是在任何子目录中不包含匹配文件的顶级目录列表,那么下面的bash one-liner就足够了:

for i in *; do test -d "$i" && ( find "$i" -name '*protein.fasta' | grep -q . || echo "$i" ); done

答案 1 :(得分:0)

#!/bin/bash

for dir in *; do

test -d "$dir" && ( find "$dir" -name '*protein.fasta' | grep -q . ||     Programfoo"$dir/$dir.DNA.fasta");
done