Answers:
find "$path" -type f | sed -e '/.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/' -e 's/.*\.//' | LC_COLLATE=C sort | uniq -c
find "$path" -type f
获取文件"$path"
夹中所有文件的递归列表。sed -e '/.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/' -e 's/.*\.//'
常用表达:
/.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/
将所有不带扩展名的文件替换为(无)。s/.*\.//
获取其余文件的扩展名。LC_COLLATE=C sort
对结果进行排序,将符号放在顶部。uniq -c
计算重复条目的数量。使用Python:
import os
from collections import Counter
from pprint import pprint
lst = []
for file in os.listdir('./'):
name, ext = os.path.splitext(file)
lst.append(ext)
pprint(Counter(lst))
输出:
Counter({'': 7,
'.png': 4,
'.mp3': 3,
'.jpg': 3,
'.mkv': 3,
'.py': 1,
'.swp': 1,
'.sh': 1})
如果您有GNU awk,则可以执行以下操作
printf '%s\0' * | gawk 'BEGIN{RS="\0"; FS="."; OFS="\t"}
{a[(NF>1 ? $NF : "(none)")]++}
END{for(i in a) print a[i],i}
'
例如,构造/增加在最后一个.
分隔的字段上键入的关联数组,或者构造一些任意的固定字符串,例如(none)
没有扩展名。
mawk
似乎不允许使用空字节记录分隔符- mawk
如果您确定不需要在文件名中处理换行符,则可以使用默认的换行符分隔符:
printf '%s\n' * | mawk 'BEGIN{FS="."; OFS="\t"} {a[(NF>1 ? $NF : "(none)")]++} END{for(i in a) print a[i],i}'
使用基本/bin/sh
甚至bash
是任务可能会有些困难,但是正如您在其他答案中所看到的那样,可用于聚合数据的工具可以非常轻松地处理此类任务。这样的工具之一就是sqlite
数据库。
使用sqlite
数据库的最简单过程是创建一个.csv
具有两个字段的文件:文件名和扩展名。以后sqlite
可以使用简单的聚合语句COUNT()
与GROUP BY ext
基于扩展字段的文件计数
$ { printf "file,ext\n"; find -type f -exec sh -c 'f=${1##*/};printf "%s,%s\n" "${1}" "${1##*.}"' sh {} \; ; } > files.csv
$ sqlite3 <<EOF
> .mode csv
> .import ./files.csv files_tb
> SELECT ext,COUNT(file) FROM files_tb GROUP BY ext;
> EOF
csv,1
mp3,6
txt,1
wav,27
files_tb
我认为正在引用表,但未在任何可见的地方定义表列?
printf
。并且SQLite将默认将csv文件的第一行作为列名。
如果可以的话,使用PowerShell:
Get-ChildItem -File | Group-Object Extension -NoElement
或更短,使用别名:
ls -file | group -n Extension
ext = [ f.split('.')[-1] for f in os.listdir('./') ]
困扰,例如 Thatll使它的行数更短,甚至可能更Python化