我目前知道如何搜索目录并列出不包含特定文件的目录,如下所示:
find parent_directory -mindepth 1 -maxdepth 1 -type d '!' -exec sh -c 'ls -1 "{}"|egrep -i -q "^file_name$"' \; -print
但现在我想使用结果目录来检查它们是否包含另一个文件,但我无法在扩展的单行表达式中做到这一点。这有可能吗?
答案1
您还可以通过以下方式确定所需的目录:
find . -maxdepth 2 -path '*/*/wanted.txt' -type f \
-execdir test ! -f unwanted.txt \; -execdir pwd \;
其工作原理如下:
- 我们寻找深度为 2 的条目。
- 由于存在 2 个斜杠,该
-path
选项将进一步将它们限制为深度为 2,因为最大深度阻止进一步前进,并且 2 个显式斜杠阻止深度低于 2。 - 在深度级别 2 找到的 Wanted.txt 条目最好是一个常规文件,并通过以下方式确保
-type f
- 该
-execdir
选项会将操作提升到 Wanted.txt 所在的目录,因此该test
命令将在那里查找不需要的文件。 -execdir
接下来,打印未找到不需要的文件的目录(由于 而提升)是一个简单的问题。- 无意详述这一点,一个目录只能包含一次特定文件,因此
-execdir
操作在 /directory 上运行一次,并且仅在那些至少确定包含 Wanted.txt 常规文件的目录上运行。
答案2
You are making this far more complicated than needed. You don't seem to want to recurse into subdirectories, so all you need to find those directories that don't have a specific file is:
for dir in */; do [ ! -e "$dir"/"$filename" ] || printf '%s\n' "$dir"; done
并且,要查看其中哪些确实有另一个文件:
for dir in */; do
[ ! -e "$dir"/"$filename1" ] &&
[ -e "$dir"/"$filename2" ] &&
printf '%s\n' "$dir";
done
或者,用稍微清晰的语法:
for dir in */; do
if [ ! -e "$dir"/"$filename1" ]; then
if [ -e "$dir"/"$filename2" ]; then
printf '%s\n' "$dir";
fi
fi
done
这一切都是使用 shell 的内置工具完成的。具体来说:
[
:这个以及随附的内容]
是内置函数的同义词test
(请参阅help [
或help test
如果使用 sh 风格的 shell)。它们是在 shell 中编写测试操作的方法。-e
:这测试文件/目录等是否存在。看help test
。简单的格式是:如果存在[ -e file ]
则返回 true 。file
[ ! -e filename ]
:!
简单地反转测试。如果确实如此,那[ ! -e file ]
就是真的file
不是存在。
总而言之,这意味着上面的命令执行以下操作:
## Iterate over every directory (dirs only because of the '/' in '*/')
## saving each of them in the variable $dir.
for dir in */; do
## If this $dir does not contain $filename1
if [ ! -e "$dir"/"$filename1" ]; then
## If this $dir does contain $filename2
if [ -e "$dir"/"$filename2" ]; then
## Print the directory name
printf '%s\n' "$dir";
fi
fi
done
当然,要运行它,您需要首先进行$filename1
相应的设置$filename2
。例如:
filename1="unwantedFile"
filename2="wantedFile"
答案3
使用zsh
, 列出当前目录中包含文件musthave
而不是mustnothave
文件的目录:
contain() [[ -e $REPLY/$1 || -L $REPLY/$1 ]]
printf '%s\n' *(D/e(contain musthave)^e(contain mustnothave))
请注意,执行以下操作:
find ... -exec sh -c 'ls {}' \;
不仅不可移植,而且还是一个命令注入漏洞。例如,如果有一个名为$(reboot)
或 的目录;reboot
,则会运行ls $(reboot)
或ls ;reboot
命令行,从而导致重新启动。{}
永远不应该嵌入到(或任何其他语言的)代码参数中,sh
否则可能会被误解。使用:
find ... -exec sh -c 'ls "$1"' sh {} \;
反而。