如何在文件夹层次结构中find所有不同的文件扩展名?

在Linux机器上,我想遍历一个文件夹层次结构,并获取其中所有不同文件扩展名的列表。

从shell中实现这个最好的方法是什么?

尝试这个(不知道这是否是最好的方法,但它的工作原理):

find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u 

它的工作如下:

  • 查找当前文件夹中的所有文件
  • 打印文件的扩展名(如果有的话)
  • 做一个独特的sorting列表

awk可以做到这一切:

 find . -type f | awk -F. '!a[$NF]++{print $NF}' 

recursion版本:

 find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort -u 

如果你想要总计(看到延长的次数):

 find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort | uniq -c | sort -rn 

非recursion(单个文件夹):

 for f in *.*; do printf "%s\n" "${f##*.}"; done | sort -u 

我基于这个论坛post ,信贷应该去那里。

电源shell:

 dir -recurse | select-object extension -unique 

感谢http://kevin-berridge.blogspot.com/2007/11/windows-powershell.html

用点findeverythin,只显示后缀。

 find . -type f -name "*.*" | awk -F. '{print $NF}' | sort -u 

如果你知道所有的后缀都有3个字符的话

 find . -type f -name "*.???" | awk -F. '{print $NF}' | sort -u 

或与sed显示所有后缀1到4个字符。 将{1,4}更改为您在后缀中预期的字符范围。

 find . -type f | sed -n 's/.*\.\(.\{1,4\}\)$/\1/p'| sort -u 

添加我自己的变化混合。 我认为这是最简单的,当效率不是一个大问题时,它可能是有用的。

 find . -type f | grep -o -E '\.[^\.]+$' | sort -u 

我在这里试了一堆答案,甚至是“最好”的答案。 他们都没有达到我特别追求的目标。 所以,除了过去12个小时的坐在正则expression式代码多个程序和阅读和testing这些答案,这是我想出了哪些作品是完全像我想要的。

  find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{3,6}" | awk '{print tolower($0)}' | sort -u 
  • 查找所有可能有扩展名的文件。
  • 只恳求扩展名
  • 请注意3到6个字符之间的文件扩展名(如果不符合您的需要,请调整数字)。 这有助于避免caching文件和系统文件(系统文件位是search监狱)。
  • Awk以小写字母打印扩展名。
  • sorting并引入唯一的值。 本来我试图尝试awk的答案,但它会加倍打印大小写敏感的项目。

如果您需要计算文件扩展名,请使用下面的代码

 find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{3,6}" | awk '{print tolower($0)}' | sort | uniq -c | sort -rn 

虽然这些方法需要一些时间才能完成,可能不是解决问题的最佳方法,但它们是可行的。

在Python中,使用包含空白扩展名的非常大的目录生成器,并获取每个扩展名显示的次数:

 import json import collections import itertools import os root = '/home/andres' files = itertools.chain.from_iterable(( files for _,_,files in os.walk(root) )) counter = collections.Counter( (os.path.splitext(file_)[1] for file_ in files) ) print json.dumps(counter, indent=2) 

既然已经有另一个使用Perl的解决scheme:

如果你安装了Python,你也可以(从shell):

 python -c "import os;e=set();[[e.add(os.path.splitext(f)[-1]) for f in fn]for _,_,fn in os.walk('/home')];print '\n'.join(e)" 

到目前为止,没有一个回复处理文件名与正确的换行符(除了ChristopheD,刚刚进来,因为我正在打字)。 以下不是一句话,而是作品,而且速度相当快。

 import os, sys def names(roots): for root in roots: for a, b, basenames in os.walk(root): for basename in basenames: yield basename sufs = set(os.path.splitext(x)[1] for x in names(sys.argv[1:])) for suf in sufs: if suf: print suf 

你也可以这样做

 find . -type f -name "*.php" -exec PATHTOAPP {} +