我需要搜索并查找包含某个文件的子目录,但是如果它们包含这个某个文件+另一个文件,我不希望列出它们。
该声明看起来像这样:
- 查找包含文件“password.old”的目录
- 如果目录包含“password.old”和“webvirtual”,则不要列出它们
- 如果目录仅包含“password.old”且不包含“webvirtual”,则输出目录路径到 > OLD.TXT 文件
这是我目前所拥有的,这完全错了吗?它似乎工作正常,但我对 bash 脚本还很陌生,只是想确保我没有遗漏任何东西……或者也许有更好的方法来处理这个问题?
#!/bin/sh
if FILE=$(find ./ -path OLD/ -prune -o -name "password.old") && FILE=$(find ./ -path OLD/ -prune -o -name "webvirtual*")
then
printf %"s\n" $FILE > Not_Old_Ones.txt
fi
if FILE=$(find ./ -path OLD/ -prune -o -name "password.old") && FILE=$(find ./ -path OLD/ -prune -o ! -name "webvirtual*")
then
printf %"s\n" $FILE > Old_Ones.txt
fi
答案1
我会做:
find . -path ./OLD -prune -o -name password.old \
! -execdir [ -e webvirtual ] \; -printf '%h\n'
-execdir
存在于 GNU find
(自 4.2.12 (2005) 起)sfind
和大多数 BSD(它的来源)中。-printf
是 GNU 特定的。您可以将其替换-execdir pwd \;
为其他find
实现。
如果-execdir
不可用:
find . -path ./OLD -prune -o -name password.old -exec sh -c '
for file do
dir=${file%/*}
[ -e "$dir/webvirtual" ] || printf "%s\n" "$dir"
done' sh {} +
上面是 POSIX。在 Solaris 10 及更早版本上,请务必使用sh
中的标准/usr/xpg4/bin
,而不是 中的标准/bin
。
答案2
有点长,但可行的解决方案,应该适用于-execdir
不可用的情况:
$ tree
.
├── dir_one
│ ├── password.old
│ └── webvirtual
└── dir_two
└── password.old
$ find . -iname "*password.old" -exec dirname "{}" \; 2>/dev/null | while IFS= read -r directory; do
> [ -e "$directory"/webvirtual ] && continue || echo "$directory"
> done
./dir_two
因此,您现在需要做的就是> OLD.txt
在语句末尾添加done
将输出重定向到文件
如果该dirname
命令不可用,您可以使用以下脚本并将目录作为参数。
#!/bin/sh
find "$1" -type f -iname "*password.old" -printf "%h\n" |
while IFS= read -r directory;
do
[ -e "$directory"/webvirtual ] && continue || echo "$directory"
done
例如:
$ ./find_missing_webvirtual.sh ./TESTDIR/
./TESTDIR/dir_two