在Linux机器上,我希望遍历一个文件夹层次结构,并获得其中所有不同文件扩展名的列表。
从外壳中实现这一点的最佳方法是什么?
在Linux机器上,我希望遍历一个文件夹层次结构,并获得其中所有不同文件扩展名的列表。
从外壳中实现这一点的最佳方法是什么?
当前回答
我发现它简单快捷……
# find . -type f -exec basename {} \; | awk -F"." '{print $NF}' > /tmp/outfile.txt
# cat /tmp/outfile.txt | sort | uniq -c| sort -n > tmp/outfile_sorted.txt
其他回答
我的无awk、无sed、无perl、无python的posix兼容替代方案:
find . -type f | rev | cut -d. -f1 | rev | tr '[:upper:]' '[:lower:]' | sort | uniq --count | sort -rn
诀窍在于它将行反转,并在开始处切断扩展。 它还将扩展名转换为小写。
示例输出:
3689 jpg
1036 png
610 mp4
90 webm
90 mkv
57 mov
12 avi
10 txt
3 zip
2 ogv
1 xcf
1 trashinfo
1 sh
1 m4v
1 jpeg
1 ini
1 gqv
1 gcs
1 dv
试试这个(不确定是不是最好的方法,但确实有效):
find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
它的工作原理如下:
找到当前文件夹中的所有文件 打印文件扩展名(如果有的话) 制作一个唯一的排序列表
我发现它简单快捷……
# find . -type f -exec basename {} \; | awk -F"." '{print $NF}' > /tmp/outfile.txt
# cat /tmp/outfile.txt | sort | uniq -c| sort -n > tmp/outfile_sorted.txt
我试了很多答案,甚至是“最好的”答案。他们都没有达到我的要求。所以除了过去12个小时坐在多个程序的正则表达式代码中,阅读和测试这些答案之外,这就是我想出的工作方式,完全像我想要的那样。
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort -u
查找可能具有扩展名的所有文件。 Greps只有扩展 2到16个字符之间的文件扩展名(如果它们不符合您的需要,只需调整数字)。这有助于避免缓存文件和系统文件(系统文件位是搜索jail)。 Awk以小写打印扩展名。 排序并只带来唯一的值。最初,我试图尝试awk的答案,但它会双打印项目,不同的大小写敏感性。
如果你需要文件扩展名的计数,那么使用下面的代码
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort | uniq -c | sort -rn
虽然这些方法需要一些时间才能完成,而且可能不是解决问题的最佳方法,但它们是有效的。
更新: 每个@alpha_989长的文件扩展名将导致一个问题。这是由于原始正则表达式“[[:alpha:]]{3,6}”。我已经更新了答案,包括正则表达式“[[:alpha:]]{2,16}”。然而,任何使用这段代码的人都应该知道,这些数字是最终输出所允许的扩展长度的最小值和最大值。任何超出这个范围的内容都将在输出中被分割成多行。
注:原来的帖子读的是“-文件扩展名在3到6个字符之间的Greps(如果它们不适合你的需要,只需调整数字)。这有助于避免缓存文件和系统文件(系统文件位是搜索监狱)。
想法:可以通过以下方式来查找特定长度的文件扩展名:
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{4,}" | awk '{print tolower($0)}' | sort -u
其中4是要包含的文件扩展名长度,然后还查找超出该长度的任何扩展名。
递归版本:
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
非递归(单个文件夹):
for f in *.*; do printf "%s\n" "${f##*.}"; done | sort -u
我是根据这个论坛帖子写的,功劳应该在那里。