我有一个包含数千个文件夹的文件夹结构。我希望能够找到所有文件夹,例如,包含多个 .txt 文件、多个 .jpeg 或其他任何文件夹,而不会看到任何仅包含此类单个文件的文件夹。
这些文件夹都应该只有一个特定类型的文件,但情况并非总是如此,并且尝试查找它们很乏味。
请注意,文件夹可能包含许多其他文件。
如果可能,我想将“FILE.JPG”和“file.jpg”匹配为匹配“file”或“jpg”的查询。
我一直在做的只是find . -iname "*file*"
手动完成。
文件夹包含文件夹,有时有 3 或 4 层深
first/
second/
README.txt
readme.TXT
readme.txt
foo.txt
third/
info.txt
third/fourth/
raksljdfa.txt
应该返回
first/second/README.txt
first/second/readme.TXT
first/second/readme.txt
first/secondfoo.txt```
搜索“txt”时
和
first/second/README.txt
first/second/readme.TXT
first/second/readme.txt
搜索“自述文件”时
这个纯 Bash 代码应该这样做(注意事项,见下文):
#! /bin/bash
fileglob=$1 # E.g. '*.txt' or '*readme*'
shopt -s nullglob # Expand to nothing if nothing matches
shopt -s dotglob # Match files whose names start with '.'
shopt -s globstar # '**' matches multiple directory levels
shopt -s nocaseglob # Ignore case when matching
IFS= # Disable word splitting
for dir in **/ ; do
matching_files=( "$dir"$fileglob )
(( ${#matching_files[*]} > 1 )) && printf '%s\n' "${matching_files[@]}"
done
运行程序时,将要匹配的模式作为参数提供给程序。例如
myprog '*.txt'
myprog '*readme*'
(模式上的引号是阻止它们匹配当前目录中的文件所必需的。)
关于代码的警告是:
globstar
是在 Bash 4.0 中引入的。该代码不适用于较旧的 Bash。globstar
匹配遵循符号链接。这可能会导致重复输出,甚至由于循环链接而导致失败。**/
模式扩展为层次结构中所有目录的列表。如果目录数量很大(例如,大于一万),这可能需要很长时间或使用过多的内存。如果您的 Bash 版本早于 4.3,或者您有大量目录,则此代码是更好的选择:
#! /bin/bash
fileglob=$1 # E.g. '*.txt' or '*readme*'
shopt -s nullglob # Expand to nothing if nothing matches
shopt -s dotglob # Match files whose names start with '.'
shopt -s nocaseglob # Ignore case when matching
IFS= # Disable word splitting
find . -type d -print0 \
| while read -r -d '' dir ; do
matching_files=( "$dir"/$fileglob )
(( ${#matching_files[*]} > 1 )) \
&& printf '%s\n' "${matching_files[@]}"
done
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句