我试图循环遍历目录中属于文件夹的文件列表,如果是这样,则列出这些文件夹的子目录,并且在该子目录中时,仅列出那些与 grep 表达式不匹配的文件。但是,我没有得到任何grep
包含表达式的返回结果。
例如:
for file in "ML"*; do if [ -d "$file" ]; then ls "$file" | grep -q -F "venv" ; fi; done
不会打印出任何内容。
该子目录如下所示:
MachineLearning ROC.png bin requirements.txt venv
ACTION_batched.py PUT3.py test1.py
ACTION_custom.py RML test2.py
Case scenarios.docx Tutorials venv
ENV_DIR act_2.py week1
Introduction to essay.docx bin week2
MLschema.docx cookies.js week3
POST.py exercises week4
POST_T.py plots week5
PUT.py requirements.txt week6
PUT2.py somefig.jpeg week7
答案1
要查找匹配的目录,您可以简单地使用
printf '%s\n' ML*/venv/
cut -d / -f1
如果您只想要目录名称,也许可以通过管道连接。
如果您的目录名称带有换行符,则这将无法完全正确工作;也许还可以看到https://mywiki.wooledge.org/BashFAQ/020
您的尝试的问题是grep -q
没有打印任何内容。最小的修复方法是删除-q
;但当然,这可以使用单个通配符来解决,如上所述。
如果您想要不匹配的目录(对此最小的修复是grep -v
否定搜索),请尝试类似的操作
for file in ML*/*/; do
case $file in
*/venv/) continue;;
esac
: continue with "$file"
done
最后的尾部斜杠将通配符限制为仅匹配目录;如果你也想匹配常规文件,你也必须从case
匹配表达式中取出它venv
。
该关键字放弃最内层或循环continue
的当前迭代,并跳到下一次迭代(或循环末尾,如果这是最后一次迭代)。for
while
如果您以前没有遇到过这种语法,它case
可能看起来令人生畏或神秘,但您很快就会习惯它。它非常通用,可以让您轻松指定替代方案,例如
*/venv/ | */ENV_DIR/) continue;;
它还可以移植回原始的 Unix v7 Bourne shell。
Bash 和 Ksh 有一个扩展的通配工具,可以让你说类似的话,ML*/!(venv)
但它不可移植。