如何递归计算 Linux 目录列表中的文件?
例子:
/dog/
/a.txt
/b.txt
/c.ipynb
/cat/
/d.txt
/e.pdf
/f.png
/g.txt
/owl/
/h.txt
我想要以下输出:
5 .txt
1 .pynb
1 .pdf
1 .png
我尝试了以下方法,但没有运气。
find . -type f | sed -n 's/..*\.//p' | sort | uniq -c
使用 Perl 单行符以您需要的格式输出,如下所示:
find . -type f | perl -pe 's{.*[.]}{.}' | sort | uniq -c | perl -lane 'print join "\t", @F;' | sort -nr
Perl 单行器使用这些命令行标志:
-e
:告诉 Perl 查找内联代码,而不是在文件中。
-n
:一次循环输入一行,$_
默认情况下将其分配给。
-p
:一次循环输入一行,$_
默认情况下将其分配给。print $_
在每次循环迭代后添加。
-l
: 在执行内联代码之前去除输入行分隔符("\n"
默认情况下在 *NIX 上),并在打印时附加它。:在空格或选项中指定的正则表达式上
-a
拆分$_
为数组。@F
-F
还请参见
perldoc perlrun
::如何执行 Perl 解释器:命令行开关
perldoc perlrequick
:Perl 正则表达式快速入门
这find + gawk
可能对您有用:
find . -type f -print0 |
awk -v RS='\0' -F/ '{sub(/^.*\./, ".", $NF); ++freq[$NF]} END {for (i in freq) print freq[i], i}'
使用-print0
infind
处理带有空格和其他特殊 glob 字符的文件是安全的。同样,我们使用-v RS='\0'
inawk
来确保NUL
byte 是记录分隔符。
假设您有一个已知目录path
,其中包含以下子目录foo
, bar
, baz
, qux
, quux
,gorge
并且我们希望根据扩展名计算文件类型,但仅针对子目录foo
,baz
和qux
最好的就是做
$ find /path/{foo,baz,qux} -type f -exec sh -c 'echo "${0##*.}"' {} \; | sort | uniq -c
exec 部分仅使用简单的sh
变量替换来打印扩展名。