循环遍历文件并列出那些不包含字符串的文件

循环遍历文件并列出那些不包含字符串的文件

我试图循环遍历目录中属于文件夹的文件列表,如果是这样,则列出这些文件夹的子目录,并且在该子目录中时,仅列出那些与 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的当前迭代,并跳到下一次迭代(或循环末尾,如果这是最后一次迭代)。forwhile

如果您以前没有遇到过这种语法,它case可能看起来令人生畏或神秘,但您很快就会习惯它。它非常通用,可以让您轻松指定替代方案,例如

    */venv/ | */ENV_DIR/) continue;;

它还可以移植回原始的 Unix v7 Bourne shell。

Bash 和 Ksh 有一个扩展的通配工具,可以让你说类似的话,ML*/!(venv)但它不可移植。

相关内容