如何递归查找目录树中首行首字符为空格、制表符或换行符的文件
嘿,这个需求我平时处理文件的时候经常遇到,给你几个实用的命令行方案,都能轻松搞定递归查找的问题:
方法1:
find + awk组合(推荐,高效) 这个方案在查找过程中直接处理文件,不需要额外多次调用工具,效率更高。命令如下:
find /path/to/your/directory -type f -exec awk 'NR==1 { if (/^[ \t\n]/) { print FILENAME; exit } }' {} \;
拆解一下每个部分的作用:
find /path/to/your/directory:替换成你要递归查找的根目录就行,当前目录直接用.-type f:只筛选普通文件,跳过目录、符号链接这些非文件项-exec awk '...' {} \;:对每个找到的文件执行后面的awk脚本- awk脚本里的
NR==1:只处理文件的第一行,不用遍历整个文件 /^[ \t\n]/:正则匹配首行开头是空格、制表符或者**换行符(空行)**的情况- 一旦匹配成功,就打印文件名
FILENAME,然后exit退出awk,避免浪费资源处理文件其他内容
方法2:
find + head + grep组合(更易读) 如果觉得awk的语法有点绕,这个组合逻辑更直观,容易理解:
find /path/to/your/directory -type f -exec sh -c 'head -n1 "$1" | grep -q "^[ \t]" || head -n1 "$1" | grep -q "^$"' {} \; -print
解释一下逻辑:
head -n1 "$1":提取目标文件的第一行内容grep -q "^[ \t]":静默模式下检查首行是否以空格或制表符开头|| head -n1 "$1" | grep -q "^$":如果上面没匹配到,就检查第一行是不是空行(也就是首字符是换行符)-print:只有当前面的条件满足时,才打印该文件的路径
额外小技巧
- 要是想排除特定类型的文件(比如
.log日志文件),可以给find加个排除规则:find . -type f ! -name "*.log" -exec awk 'NR==1 { if (/^[ \t\n]/) { print FILENAME; exit } }' {} \; - 跨系统兼容的话,把正则里的
[ \t]换成[[:blank:]]更稳妥,[:blank:]是POSIX标准的空白字符(包含空格和制表符),在Linux、macOS上都能用:find . -type f -exec awk 'NR==1 { if (/^[[:blank:]\n]/) { print FILENAME; exit } }' {} \;
内容的提问来源于stack exchange,提问作者Lawrence
相关产品推荐
相关产品推荐

