我想检查当前目录中是否没有.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