ファイルを繰り返し、文字列を含まないファイルを一覧表示します。

ファイルを繰り返し、文字列を含まないファイルを一覧表示します。

フォルダに属するディレクトリ内のファイルのリストを繰り返しながら、そのフォルダのサブディレクトリを一覧表示し、そのサブディレクトリにある間に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シェルに再移植することもできます。

BashとKshには同様のことを言うことができる拡張されたグロービングツールがありますが、ML*/!(venv)移植性はありません。

関連情報