Linux 检查目录中是否存在特定的文件类型/扩展名
使用bash如何判断目录中是否存在特定扩展名的文件 差不多Linux 检查目录中是否存在特定的文件类型/扩展名,linux,bash,shell,Linux,Bash,Shell,使用bash如何判断目录中是否存在特定扩展名的文件 差不多 if [ -e *.flac ]; then echo true; fi 你需要认真考虑在你的if语句中加入哪个标志,以及它与你想要的结果的关系 如果只检查常规文件,而不检查其他类型的文件系统条目,则需要将代码框架更改为: if [ -f file ]; then echo true; fi 使用-f将if限制为常规文件,而-e更具扩展性,将匹配所有类型的文件系统条目。当然还有其他选项,如目录的-d,等等。请参阅以获得一个好的
if [ -e *.flac ]; then
echo true;
fi
你需要认真考虑在你的
if
语句中加入哪个标志,以及它与你想要的结果的关系
如果只检查常规文件,而不检查其他类型的文件系统条目,则需要将代码框架更改为:
if [ -f file ]; then
echo true;
fi
使用-f
将if
限制为常规文件,而-e
更具扩展性,将匹配所有类型的文件系统条目。当然还有其他选项,如目录的-d
,等等。请参阅以获得一个好的列表
正如@msw所指出的,test
(即[
)如果尝试向其提供多个参数,则会阻塞。如果*.flac
的glob返回多个文件,则可能会发生这种情况。在这种情况下,请尝试将if
测试包装在如下循环中:
for file in ./*.pdf
do
if [ -f "${file}" ]; then
echo 'true';
break
fi
done
通过这种方式,您可以在所需文件扩展名的第一个实例上中断,并继续执行脚本的其余部分。bash only:
#!/bin/bash
files=$(ls /home/somedir/*.flac 2> /dev/null | wc -l)
if [ "$files" != "0" ]
then
echo "Some files exists."
else
echo "No files with that extension."
fi
any_with_ext () (
ext="$1"
any=false
shopt -s nullglob
for f in *."$ext"; do
any=true
break
done
echo $any
)
if $( any_with_ext flac ); then
echo "have some flac"
else
echo "dir is flac-free"
fi
我使用括号而不是大括号来确保使用子shell(不想破坏当前的nullglob
设置)。这使用ls(1),如果不存在flac文件,ls报告错误并退出脚本;否则脚本将继续,文件可能会被处理
#! /bin/sh
ls *.flac >/dev/null || exit
## Do something with flac files here
顶级解决方案(if[-e*.flac];)
对我不起作用,给出:[:参数太多
如果ls*.flac>/dev/null 2>&1;
那么它将工作。这里有一个解决方案,它不使用外部命令(即,不使用ls
),而是使用shell函数。在bash中测试:
shopt -s nullglob
function have_any() {
[ $# -gt 0 ]
}
if have_any ./*.flac; then
echo true
fi
函数
have_any
使用$
对其参数进行计数,并使用[$\35;-gt 0]
然后测试是否至少有一个参数。在调用have\u any
时,使用/*.flac
而不仅仅是*。flac
是为了避免名为--help
的文件引起的问题。您可以使用-f检查特定类型的文件是否存在:
#!/bin/bash
if [ -f *.flac ] ; then
echo true
fi
完成时,使用zsh:
if [[ -n *.flac(#qN) ]]; then
echo true
fi
这列在zsh手册章节的末尾。由于
[
禁用文件名全局绑定,我们需要在全局绑定字符串的末尾使用(#q)
,然后使用N
标志(NULL\u GLOB
选项)强制生成文件名如果没有匹配项,则强制生成的字符串为空。这里有一个相当简单的解决方案:
if[“$(ls-A | grep-i\\.flac\$)”];则echo true;fi
正如您所看到的,这只是一行代码,但它工作得足够好。它应该可以与bash以及与posix兼容的shell(如dash)一起工作。它也不区分大小写,并且不关心存在什么类型的文件(常规、符号链接、目录等),如果您有一些符号链接或其他内容,这可能会很有用。我尝试了以下方法:
if [ -f *.html ]; then
echo "html files exist"
else
echo "html files dont exist"
fi
我对其他文件使用这段代码没有任何问题,但对于html文件,我收到了一个:
然后我尝试了@JeremyWeir的计数解决方案,这对我很有效:
count=`ls -1 *.flac 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo true
fi
请记住,如果在循环中执行此操作,则必须重置计数:
count=$((0))
这应该适用于任何类似外壳的情况:
if [ "$(find . -maxdepth 1 -type f | grep -i '.*\.flac$')" ]; then
echo true
fi
这也适用于GNUfind
,但如果它与find
的其他实现兼容,则使用IDK:
if [ "$(find . -maxdepth 1 -type f -iname \*.flac)" ]; then
echo true
fi
除了
test
(又名[
)抱怨模式扩展到多个文件外:“需要二进制运算符”或“参数太多”@msw-谢谢,我甚至没有想到这个问题。我已尝试修改我的答案以将其考虑在内。你应该引用变量,即使用“$file”
,因为文件名可能包含一些不正确的字符,如空格或星号。这是错误的。首先,您可能指的是-ge
,而不是-gt
,因为否则您的代码将检测不到单个文件。其次,如果没有与模式匹配的文件,任何符合要求的shell都将保留字符串*.ext
untouched,所以您仍然会得到一个“结果”。$#对于单个文件是1,对于没有文件是0。这一个很好,因为您可以在找到文件后对文件执行一些操作。+1对于包装子shell,运行find in圆括号使myarray成为数组变量。否则,如果find不返回任何结果${myarray[@]}
equals 1还可以通过使用ls-1*.py
而不是findi来简化。如果任何文件的名称中有空格,这将把一个实例计算为两个。为了获得额外的静默,请重定向2>&1。如果版本:if ls*.flac>/dev/null 2>&1;那么……fi;
嘿,托马斯,为这个问题添加一个更好的解决方案怎么样还有Thomas,你为什么不使用它的例子是使用ls-l
,我的答案是使用ls-1
,这个答案不是解析输出,只是计算输出的行数,我几乎可以肯定,即使文件名中有奇怪的字符,ls-1
也会在每个文件中打印一行ines正在解析。如果任何文件包含\n
(是的,这在文件名中是有效的),它将返回一个错误的数字。请告诉我们,为了使行数为零,文件名中必须有什么神奇的字符?这是有效的,但您正在掩埋lede-它工作的原因是单括号[
(与更常见的[[
)相反)并不能阻止全局搜索。我喜欢这样做,因为ls-AR执行递归搜索。这有助于在解压后搜索zip存档的内容。如果目录中有多个具有给定扩展名的文件,*.html正在扩展为太多参数。例如“If”[-f file1.html file2.html];然后“。。。
[: too many arguments
count=`ls -1 *.flac 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo true
fi
count=$((0))
if [ "$(find . -maxdepth 1 -type f | grep -i '.*\.flac$')" ]; then
echo true
fi
if [ "$(find . -maxdepth 1 -type f -iname \*.flac)" ]; then
echo true
fi