我正在寻找文件的扩展名,如果文件没有扩展名,则 cut 仅给出文件名,因此我希望在没有“.”时使 cut 给出“无扩展名”。发现我用这个作为参考:https://stackoverflow.com/questions/1842254/how-can-i-find-all-of-the-distinct-file-extensions-in-a-folder-hierarchy忽略没有扩展名的文件的答案不好,因为我也需要找到这些文件
答案1
在zsh
shell 中:
print -rC1 ./**/*(.:e) | sed 's/^$/EXTENSIONLESS/' | sort | uniq -c
这将在当前目录中或当前目录下每行打印所有常规文件的所有扩展名。在对它们进行排序和计数之前,空扩展名将被EXTENSIONLESS
替换为文本。sed
**
中的 glob 与路径名中的路径zsh
名匹配/
(“递归地”),就像在该 shell 中设置 shell 选项bash
时的相同模式一样。globstar
(.:e)
模式末尾的 是一个全局限定符,它使前面的模式仅匹配常规文件,(.)
并从每个匹配名称 ( ) 中删除除扩展名之外的所有内容:e
。
同样的事情,但是dummy.EXTENSIONLESS
使用表达式将无扩展名文件名替换为通配表达式中的文件名e['...']
,从而摆脱了调用sed
:
print -rC1 src/**/*(.e['[ -z $REPLY:e ] && REPLY=dummy.EXTENISONLESS']:e) | sort | uniq -c
在非zsh
shell 中,您可以使用find
内联 shell 脚本来执行上述管道的前几个部分:
find . -type f -exec sh -c '
for pathname do
name=${pathname##*/}
case $name in
*.?*)
printf "%s\n" "${name##*.}" ;;
*)
echo EXTENSIONLESS
esac
done' sh {} + | sort | uniq -c
这用于find
查找当前目录中或当前目录下的所有常规文件。对于这些文件的批次,它会调用内联 shell 脚本。该脚本迭代当前的路径名集并将每个路径名的文件名部分提取到变量中name
。然后,它测试是否$name
包含一个点,后跟至少一个其他字符。如果名称中有点(后面跟什么),则打印点后面的部分;否则,EXTENTSIONLESS
打印该字符串。
find
然后以与之前相同的方式对 的输出进行排序和计数。
请注意,上面的代码将调用类似hello.
扩展名的名称,而.bashrc
将具有扩展名bashrc
.将模式更改*.?*
为*?.?*
要求点两侧都有一个字符(将被.bashrc
视为无扩展名)。