
.gridで終わるファイルを含む親ディレクトリのすべてのディレクトリを見つけて一覧表示したいと思います。/work/user/folder1/*/*
find /work/user/folder1/*/*/ '!' -mindepth 1 -maxdepth 1 -name *.grid
次にやりたいことは、.gridで終わるファイルが見つからないすべてのディレクトリを見つけることです。デフォルトでは、欠落しているフォルダを印刷するコマンドが必要です。
どうすればいいですか?
答え1
find
電話をかけるときに使用してくださいfind
!
find . -type d \( -exec sh -c 'cd "$0"; find . \( -name . -o -prune \) -name "*.grid" | grep -q .' {} \; -o -print \)
これはPOSIXに準拠しています。この回答ありがとうございます。
また、ファイル名やディレクトリ名にスペース、特殊文字、改行文字が含まれているかどうかに関係なく機能します。 :)
(注:もしあなたがするディレクトリ名に特殊文字または改行文字が含まれている場合は、-print
最終mainをディレクトリ内の必要に応じて変更する必要があります。これは、.のみを使用すると結果の印刷リストを安全に解析できないためです-print
。 )
以下は、読みやすくするために誤解を招く改行文字が追加されたバージョンです。
find . -type d \
\( \
-exec sh -c '
cd "$0";
find . \( -name . -o -prune \) -name "*.grid" |
grep -q .
' {} \; \
-o -print \
\)
答え2
手順 1.) 該当するすべてのディレクトリのリストを作成し、英数字でソートし、重複するエントリがないことを確認します。一時ファイルにリストを保存します。
find /work/user/folder1/ [...] -type d | sort | uniq > all_directories.txt
ステップ2.)すべてのファイルのリストを作成します*.grid
。
find /work/user/folder1/ [...] -name *.grid > grid_files.txt
ステップ3。)ファイルのリストを調べて、*.grid
各ファイルのディレクトリ名を取得してから、重複するエントリがないことを確認してください。
while read FILENAME
do
echo $(dirname "$FILENAME")
done < grid_files.txt | sort | uniq > dirs_with_gridfiles.txt
ステップ4。)両方のリストを一緒に実行し、結果を並べ替えます。これで*.grid
、ファイルを含むディレクトリを一覧表示する必要があります。正確にそれぞれ2回、ディレクトリに*.grid
ファイルがありません。正確にそれぞれ一回。したがって、uniq
重複していない行のみを報告することがわかります。
cat all_directories.txt dirs_with_gridfiles.txt | sort | uniq -u > dirs_with_no_gridfile.txt
あなたはそれを得る。
答え3
これは2段階のソリューションです。全体として、プロセスは次のようになります。
*.grid
デフォルトのファイル名とリストを削除して、パス内のすべてのファイルを見つけますuniq
。これにより、1つ以上のファイルを含むすべてのディレクトリのリストが表示されます*.grid
。
$ find /work/user/folder1/*/*/ -type f -name *.grid | sed -e 's-[^/]*$--' | sort | uniq > grid-dirs.txt
- パス内のすべてのディレクトリを検索し、
grep
手順1で見つけたディレクトリをフィルタリングするために使用します。これにより、*.grid
ファイルが含まれていないすべてのディレクトリのリストが表示されます。
$ find /work/user/folder1/*/*/ -type d | grep -Fvxf grid-dirs.txt
たとえば、次のようにします。
$ find /work
/work
/work/user
/work/user/folder1
/work/user/folder1/AA
/work/user/folder1/AA/AA
/work/user/folder1/AA/DD
/work/user/folder1/AA/CC
/work/user/folder1/AA/BB
/work/user/folder1/AA/BB/foo.grid
ステップ1以降はgrid-dirs.txt
次のようになります。
/work/user/folder1/AA/BB/
ステップ2の出力は次のとおりです。
$ find /work/user/folder1/*/*/ -type d | grep -Fvxf grid-dirs.txt
/work/user/folder1/AA/AA/
/work/user/folder1/AA/CC/
/work/user/folder1/AA/DD/
答え4
Bash v4(またはそれ以上)を使用している場合は、*.grid
ループ内のすべてのファイルとすべてのディレクトリを通過して、ファイルが存在するディレクトリと存在しないディレクトリを一覧表示する内部ループも見つけることができると思います。 Bash v4では、通常無効になっているオプションの1つを使用します。
(
# 'globstar' enables '**' expansions, which instructs
# the shell to search all and below recursively
shopt -s globstar
# Note that '**' is implicitly recursive, no need to specify
# depth. If you do want to specify precise depth, then use a
# '*/' for each wanted depth, like '*/*/*/' for 3 depths
for f in /work/user/folder1/**/*.grid; do
f="${f##*/}" # strip directory from found name
printf '\nNow looking for: %s\n' "$f"
# A simple '**/' returns directories only
for d in /work/user/folder1/**/; do
# simple existence test
[ -e "${d}${f}" ] && \
printf ' present in %s\n' "$d" || \
printf 'not present in %s\n' "$d"
done
done
)
残念ながら、**
構文はPOSIXではありません。
ただし、検索する必要がある正確な深さがわかっている場合は、そのコマンドを削除して各コマンドを繰り返し表現されたshopt
正確**/
な深さに変換すると、*/
POSIXシェルでもうまく機能します。