我需要一个 Bash 脚本来为所有没有特定文件的目录执行一个程序,并在同一目录上创建输出文件。该程序需要一个输入文件,该文件存在于每个目录中,名称为 * .DNA.fasta。假设我有以下目录,也可能包含子目录
dir1/a.protein.fasta
dir2/b.protein.fasta
dir3/anyfile
dir4/x.orf.fasta
我首先查找不包含名称为 *. Protein.fasta
的特定文件的目录
在本例中,我希望列出 dir3
和 dir4
(因为它们不包含 *. Protein.fasta
)
我已经尝试过这段代码:
find . -maxdepth 1 -type d \! -exec test -e '{}/*protein.fasta' \; -print
但似乎我错过了一些不起作用的东西。 我也不知道如何继续整个故事。
最佳答案
这是一个棘手的问题。
我想不出一个好的解决方案。但无论如何,这里有一个解决方案。请注意,如果您的目录或文件名包含换行符,则保证不会工作,并且如果它们包含其他特殊字符,则不保证工作。 (我只用你问题中的样本进行了测试。)
另外,我没有包含 -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
关于linux - 用于为没有特定文件的目录运行程序的 bash 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11932067/