将“Find”命令与“if”“and”语句结合使用

将“Find”命令与“if”“and”语句结合使用

我需要搜索并查找包含某个文件的子目录,但是如果它们包含这个某个文件+另一个文件,我不希望列出它们。

该声明看起来像这样:

  1. 查找包含文件“password.old”的目录
  2. 如果目录包含“password.old”和“webvirtual”,则不要列出它们
  3. 如果目录仅包含“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

相关内容