Linux Bash脚本,用于编写包含5个以上文件的子目录

Linux Bash脚本,用于编写包含5个以上文件的子目录,linux,bash,scripting,Linux,Bash,Scripting,当我试图练习我的linux技能时,我无法解决这个问题 所以它基本上是说“编写一个以 目录作为命令参数,并打印子目录的名称 其中包含5个以上的文件。” 我原以为我们会使用find命令,但ı仍然无法理解。我的代码是: find directory -type d -mindepth5 但它不起作用。这应该可以做到: find directory/ -type f | sed 's/\(.*\)\/.*/\1/g' | sort | uniq -c | sort -n | awk '{if($1&

当我试图练习我的linux技能时,我无法解决这个问题

所以它基本上是说“编写一个以 目录作为命令参数,并打印子目录的名称 其中包含5个以上的文件。”

我原以为我们会使用
find
命令,但ı仍然无法理解。我的代码是:

find directory -type d -mindepth5 

但它不起作用。

这应该可以做到:

find directory/ -type f | sed 's/\(.*\)\/.*/\1/g' | sort | uniq -c | sort -n | awk '{if($1>5) print($2)}'
在这里使用
mindpeth
是无用的,因为它只列出至少深度为5的目录。您说您需要包含5个以上文件的子目录

find directory-type f
打印子目录中的所有文件
sed's/\(.\\)\/./\1/g'
删除文件名,只留下没有文件名的子记录列表
sort
对列表进行排序,以便我们可以使用
uniq

uniq-c
合并重复的行,并记录它发生的次数
sort-n
根据出现的次数对其进行排序(因此您将得到一个列表:(多少次,子目录))
awk'{if($1>5)print($2)}'
只打印第一个comlun为1>5的组件(并且只打印第二列)

因此,您将得到一个包含至少5个文件的子目录列表。

编辑: 建议对带有空格的路径进行修复:
应该有
awk'{if($1>5)print($2)}'
而不是
awk'{if($1>5){$1=”“;print(substr($0,2))}}'
,它将行的第一部分设置为
,然后在不带前导空格(即分隔符)的情况下打印整行。所以我们把这些放在一起:

find directory/ -type f | sed 's/\(.*\)\/.*/\1/g' | sort | uniq -c | sort -n | awk '{if($1>5){ $1=""; print(substr($0,2)) }}'

您可以使用
find
两次:

首先,您可以使用
find
wc
计算给定目录中的文件数:

nb=$(find directory -maxdepth 1 -type f -printf "x\n" | wc -l)
这只是要求
find
为目录
目录
中的每个文件在一行上输出一个
x
,以非递归方式进行,然后
wc-l
计算行数,因此,实际上,
nb
目录
中的文件数

如果您想知道一个目录是否包含5个以上的文件,最好在找到6个文件后立即停止
find

nb=$(find directory -maxdepth 1 -type f -printf "x\n" | head -6 | wc -l)
此处
nb
的上限阈值为
6

现在,如果要为目录
目录
的每个子目录输出文件数(阈值为6),可以执行以下操作:

find directory -type d -exec bash -c 'nb=$(find "$0" -maxdepth 1 -type f -printf "x\n" | head -6 | wc -l); echo "$nb"' {} \;
其中出现的
$0
0
-th参数,即
find
将替换为
目录
的子目录的
{}

最后,如果文件数超过5个,您只希望显示子目录名称:

find . -type d -exec bash -c 'nb=$(find "$0" -maxdepth 1 -type f -printf "x\n" | head -6 | wc -l); ((nb>5))' {} \; -print

最后的测试
((nb>5))
返回成功或失败,无论
nb
是否大于5,如果成功,
find
-打印子目录名。

find没有该功能,您必须找到另一种方法来计算文件数。他们想让你用bash来写。也许使用globs。这不是
-mindepth
开关的用途。它指定只包含5级深的子目录中的结果。这是您的完整脚本吗?像这样难看的东西应该可以相当有效地工作:
find directory-type d-exec bash-c'nb=$(find“$0”-maxdepth 1-type f-printf“x\n”| head-6 | wc-l);((nb>5)){}\-打印
。不太确定这是你想要的答案。不,我现在都不知道该怎么做,因为我不知道该怎么做。你好,你的代码工作得很好。你能解释一下吗?非常感谢muchAm,我说得对,它运行了一个新的
$(find“$0”-maxdepth 1-type f-printf“x\n”| head-6 | wc-l)进程;((nb>5))“
对于列出的每个文件,因此对于大量文件(例如,当尝试
/
时),速度会非常慢。”?编辑:在8000多个文件上测试您的解决方案,时间超过18秒,而我的答案在不到一秒的时间内完成相同的测试。然而,最初的问题不是关于速度。@JanLegner你是对的,这会为每个子目录产生大量的进程,并且在
/
上速度会很慢。你应该修正你的答案,使之适用于包含空格的目录名(尽管对于包含换行符的目录名是不可调整的)。