Shell:如何检查目录中是否不存在.txt文件



我想检查当前目录中是否没有.txt文件。如何在标准外壳中执行此操作?

要求:

  • 必须使用任何sh(不仅仅是bash)
  • 必须高效(一条线路没有多个功能?)

就简单性而言,它应该尽可能接近以下内容:

#! /bin/sh
[ -f ./*.txt ] || echo "Not found!"

试试这个:

if ls ./*.txt > /dev/null
then
    echo "File Exists"
else
    echo "File Doesn't exists"
fi

在这里使用find是一个不错的选择:

#!/bin/sh
res=
res=$(find . -maxdepth 1 -name '*.txt' -type f -print -quit)
[ -n "$res" ] || echo 'Not found!'

可以缩短为:

#!/bin/sh
[ -n "$(find . -maxdepth 1 -name '*.txt' -type f -print -quit)" ] || echo 'Not found!'

这样做的优点是没有shell globs,一旦找到*.txt文件find就会退出。如果.txt文件太多,您将不会得到任何参数列表太长的错误,在这种情况下也会更快。

此外,对于-type f,我们确信我们只处理文件。如果没有.txt文件,但有一个名为whatever.txt目录,那么许多涉及globs的答案都将失败。


正如@chepner在评论中所说(谢谢!),-maxdepth-quit不是由POSIX指定的,因此此解决方案是不可移植的(-printf也不是由POSIX指定的,但用-print替换-printf是一个微不足道的修复方法)。

要修复-quit开关,我们将使用grep,如下所示:

find . -name '*.txt' -type f | grep -q . || echo 'Not found!'

一旦grep读取到一个字符,它就会退出,关闭管道,find也会退出。这将在子目录中重复出现(这可能是需要的行为)。

否则,如果您不想要递归:

find . -type d ! -name . -prune ! -type d -o -name '*.txt' -type f | grep -q . || echo 'Not found!'
(echo *.txt | grep -q '*') && echo not found

跟随

( for f in *.txt; do [ -f "$f" ] && exit; done; exit 1 )

如果*.txt匹配任何内容,则$?将为0,否则为1。

(假设*.txt在不匹配任何内容时被直接处理,这在POSIX shell中应该是真的,但如果您使用bash并且设置了nullglob选项,则可能是假的。)

(更新:我合并了gniourf_gniourf关于处理*.txt可能匹配的非常规文件的建议。)

[ `printf *.txt` = '*.txt' ]

返回OP问题的答案

编辑:显式优于隐式

[ `printf *.txt` = '*.txt' ] && echo "Not found!"

编辑#2,感谢gniourf_gniourf

([ `printf *.txt` != '*.txt' ] || [ -f '*.txt' ]) && echo yes || echo no

最新更新