2

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

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

我首先找到了没有特定文件的目录,
这种情况下,我希望列出dir3and dir4(因为它们不包含*.protein.fasta)我已经尝试过这段代码:

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

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

4

2 回答 2

2

这是一个棘手的问题。

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

另外,我没有包括 a-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 单行可能就足够了:

for i in *; do test -d "$i" && ( find "$i" -name '*protein.fasta' | grep -q . || echo "$i" ); done
于 2012-08-13T11:27:14.980 回答
0
#!/bin/bash

for dir in *; do

test -d "$dir" && ( find "$dir" -name '*protein.fasta' | grep -q . ||     Programfoo"$dir/$dir.DNA.fasta");
done
于 2012-08-13T15:08:08.777 回答