在 ls 中使用 group by

在 ls 中使用 group by

我在 Windows 上使用 cygwin。

我希望计算根文件夹中的 jpeg、gif 和 png 文件的数量。

现在我可以这样做:

ls . -1R | grep '.jpeg' |  wc -l
ls . -1R | grep '.gif' |  wc -l
ls . -1R | grep '.png' |  wc -l

但是只是想,如果这里有一个group by类型语法,我可以用一个命令而不是三个命令来完成这个任务?

有小费吗?

答案1

尝试一下:

ls | awk -F '.' '{print $2}' | sort | uniq -c | sort -n

解释:

awk 在“。”处拆分文件并输出第二部分。

sort 正在对所有输出进行排序。

uniq 进行分组并按组计数

第二种排序方式是按计数对组进行排序

也许有一种方法可以改进它,即让 awk 输出最后一部分,而不是第二部分。但我忘了怎么做了,我相信他们man awk可以告诉你。

答案2

您还可以使用find

find . -name \*.jpeg -o -name \*.gif -o -name \*.png | sed 's/.*\.\([^.]\+\)/\1/' | sort | uniq -c

.这将返回扩展名下的文件数jpeggif并且png格式正确,每行一个结果:

 123 gif
 110 jpeg
1832 png

根据需要添加其他扩展。

命令解释:

  • find . -name \*.jpeg -o -name \*.gif -o -name \*.png

    搜索匹配的文件'.jpeg' 或 '.gif' 或 '*.png'。

  • sed 's/.*\.\([^.]\+\)/\1/'

    删除文件名,只保留扩展名,例如file.gif变成gif

  • sort

    排序扩展。执行此命令后,输出如下所示:

    gif
    gif
    gif
    (...)
    jpeg
    jpeg
    (...)
    png
    (...)
    
  • uniq -c

    报告发生次数。

答案3

这些解决方案适用于 bash。我不确定你是否想要每个文件类型或总数。

如果您想要了解图像文件的总数,请尝试以下操作:

ls  {*jpg,*png,*gif} | wc -l

这意味着以、或ls结尾的任何内容以及通过 的管道。jpgpnggifwc

如果您想要每个的数量,请执行以下操作:

for n in jpg png gif; do echo -ne "$n\t"; ls *$n | wc -l; done

这是一个 for 循环。它将运行 3 次,分别针对 jpg、png 和 gif 各运行一次。每次运行循环时,变量$n都会将其中一个扩展名作为值。因此,对于第一次运行,ls *$n将扩展为ls *jpgecho本质上只是表示“打印”。echo -ne表示打印时不带换行符 ( -n) 并允许使用转义字符-e,这样我就可以使用制表符\t

只要您至少拥有每种类型的一个文件,此方法就可以正常工作,否则它会发出抱怨(它仍然可以工作,只是会发出抱怨)。要获得稍微更强大的版本,请尝试以下方法:

for n in jpg png gif; do echo -ne "$n\t"; echo `ls *$n 2>/dev/null | wc -l ` || echo 0; done

此循环与上面的类似,但检查ls命令是否返回错误。bash||中的操作数表示“执行或者如果没有工作,做“。因此,我告诉 bashls *jpg等,如果它不起作用,即如果没有具有该扩展名的文件,则回显(打印)0。这2>/dev/null会导致任何错误消息被丢弃。


您还可以使用 awk(这是一个轻微修改毛罗·斯特特勒回答,这样它就只计算具有您感兴趣的扩展名的文件):

ls {*.jpg,*.png,*.gif} | awk -F'.' '{print $NF}' | sort | unic -c 

相关内容