我有一个名为 的目录dir1
,其中包含大约 800 个名为 的子目录disp-001, disp-002, ... disp-800
。我需要找到子目录
- 要么不包含文件
stdout
,要么 - 如果存在,则该文件不包含特定字符串
str1
。
识别不包含该文件的子目录的答案是另一个问题
$ find . -type d \! -exec test -e '{}/stdout' \; -print
但是,如果我尝试在上面的命令中包含 grep,它不起作用
$ find . -type d \! -exec test -e 'grep str1 {}/stdout' \; -print
如何包含字符串搜索以返回我感兴趣的目录?
答案1
您可以调整那里的任何解决方案,例如
使用
( -exec
或者-exec )
和可持续发展管理的或帕特里克的解决方案(exec
仅当第一个返回时才执行第二个false
,-print
仅当其中一个返回时才执行true
):find . -type d \( ! -exec test -f '{}/stdout' \; -o ! -exec grep -q str1 '{}/stdout' \; \) -print
甚至更短,如建议的那样科斯塔斯:
find . -type d \! -exec grep -q 'str1' {}/stdout 2>/dev/null \; -print
使用条件特登的解决方案:
for d in **/ do if [[ ! -f "$d"stdout ]] then printf '%s\n' "$d" else grep -q str1 "$d"stdout || printf '%s\n' "$d" fi done
或者,与
zsh
:print -rl **/*(/e_'[[ ! -f $REPLY/stdout ]] || ! grep -q str1 $REPLY/stdout'_)
答案2
要获取该列表,只需使用grep
:
grep -L str1 dir-*/stdout
在哪里:
-L
仅给出不匹配的文件。str1
是您要搜索的字符串。- 如果您的文件具有相同的深度,您可以使用简单的通配符。
- 如果没有,请使用
-r
标志grep
在目录中重复搜索。
- 如果没有,请使用
要继续该操作并处理该列表,您可以将其以空字节分隔(grep
s -Z
)传输到 while 循环:
grep -LZ str1 dir-*/stdout | while IFS= read -r -d '' f; do
echo "${f%%/*}" # gives the directory name
done