bash脚本tree命令返回非.dat文件,请求排查代码问题
问题分析:树状结构仅显示.dat/.DAT文件却出现其他扩展名文件
需求:仅以树状结构显示带有.dat或.DAT扩展名的文件及其所在目录,但以下三段代码执行后,会额外返回.txt、.xmlfd等其他扩展名的文件:
sudo -${user} sh -c 'cd '${userdirectory}'; find . -type f | grep -i '*.dat' | sort -u | xargs tree -L 3 -C'
sudo -${user} sh -c 'cd '${userdirectory}'; find . -type f -iname '*.dat' -exec dirname {} \; | sort -u | xargs tree -L 3 -C'
sudo -${user} sh -c 'cd '${userdirectory}'; find . -type f -name '*.[dD][aA][tT]' -exec dirname {} \; | sort -u | xargs tree -L 3 -C'
三段代码的共同核心问题
所有代码逻辑都是先找到包含.dat文件的目录,再用tree输出该目录内容,但tree命令默认会显示目录下的全部文件,不会自动过滤扩展名。哪怕你正确筛选出了.dat文件的所在目录,tree依然会把目录里的txt、xmlfd等其他文件一并列出,这就是非目标文件出现的根本原因。
各段代码的额外问题
- 第一段代码:
grep -i '*.dat'的正则表达式错误。grep默认使用正则语法,*是量词(匹配前一个字符0次或多次),这里*.dat实际会匹配任意字符(包括空)后接.dat的字符串,可能误匹配文件名中包含.dat的非目标文件(比如test.txt.dat),不过这不是导致非目标文件出现的主要问题。 - 第二段和第三段代码:
find的匹配逻辑是正确的(-iname '*.dat'和-name '*.[dD][aA][tT]'都能准确匹配.dat/.DAT文件),但后续用dirname获取目录后调用tree,依然无法避免tree显示全目录内容的问题。
解决方案
要让tree只显示.dat/.DAT文件,需要使用tree的-P参数(匹配文件名模式),结合-I参数排除其他文件,同时可以简化逻辑,不需要先用find筛选目录:
sudo -u ${user} sh -c "cd '${userdirectory}'; tree -L 3 -C -P '*.dat' -I '*'"
解释:
-P '*.dat':只显示匹配*.dat的文件(若需要忽略大小写,可改为-P '*.[dD][aA][tT]')-I '*':排除所有不匹配-P模式的文件,确保只显示.dat/.DAT文件及其所在目录- 调整引号写法,避免变量解析时出现语法错误
内容的提问来源于stack exchange,提问作者Rubberducky
相关产品推荐
相关产品推荐

