フォルダに属するディレクトリ内のファイルのリストを繰り返しながら、そのフォルダのサブディレクトリを一覧表示し、そのサブディレクトリにある間に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シェルに再移植することもできます。
BashとKshには同様のことを言うことができる拡張されたグロービングツールがありますが、ML*/!(venv)
移植性はありません。