检查目录中是否存在某种文件类型/扩展名


80

您将如何使用bash判断目录中是否存在特定扩展名的文件?

就像是

if [ -e *.flac ]; then 
echo true; 
fi 

Answers:


100
#!/bin/bash

count=`ls -1 *.flac 2>/dev/null | wc -l`
if [ $count != 0 ]
then 
echo true
fi 

9
嗨,托马斯,如何为这个问题添加一个更好的解决方案,而不仅仅是投票否决。
JeremyWeir

8
另外,托马斯(Thomas),您为什么不使用它的示例正在使用ls -l,我的答案使用的是ls -1
JeremyWeir 2015年

10
而且,这个答案并不解析输出,它只是计算的行输出,我就算有一个文件名奇怪的字符几乎可以肯定,ls -1会为每个文件打印一行
JeremyWeir

2
计数行正在解析。如果包含任何文件,它将返回不正确的数字\n(是的,在文件名中有效)。
marcelm

然后,请告诉我们,文件名中必须具有什么神奇的字符才能使行数清零?

27
#/bin/bash

myarray=(`find ./ -maxdepth 1 -name "*.py"`)
if [ ${#myarray[@]} -gt 0 ]; then 
    echo true 
else 
    echo false
fi

5
这一个是好的,因为你其实可以与文件的东西,你找到他们之后。
伊夫史密斯

+1用于在括号中包装运行中的subshel​​l,以使myarray成为数组变量。否则,如果find返回没有结果${#myarray[@]}等于1
shaffooo

也可以通过使用ls -1 *.py而不是查找来简化
JrBenito

如果任何文件名中都有空格,则将一个实例视为两个实例。
乔恩·格里菲斯

15

它使用ls(1),如果不存在flac文件,则ls报告错误,脚本退出;否则脚本将继续执行,并且文件可能会被处理

#! /bin/sh
ls *.flac  >/dev/null || exit
## Do something with flac files here

4
要获得额外的静音,请同时重定向2>&1。
贾斯珀2014年

5
如果版本:if ls *.flac >/dev/null 2>&1; then ... fi;
Josiah Yoder


3
#!/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

3

你需要小心翼翼地扔到你的旗帜上 if声明中使用,以及它与所需结果的关系。

如果您只想检查常规文件,而不要检查其他类型的文件系统条目,则需要将代码框架更改为:

if [ -f file ]; then
echo true;
fi

使用-f限制将if常规文件限制为常规文件,但-e扩展性更强,并且将匹配所有类型的文件系统条目。当然,还有其他选项,例如-d目录等。请参见http://tldp.org/LDP/abs/html/fto.html以获得良好的列表。

正如@msw指出的那样,如果您尝试为它提供多个参数,则test(即[)将会阻塞。如果您的glob*.flac返回多个文件,则可能会发生这种情况。在这种情况下,请尝试将if测试包装成一个循环:

for file in ./*.pdf
do
    if [ -f "${file}" ]; then
    echo 'true';
    break
    fi
done

这样,您break就可以在想要的文件扩展名的第一个实例上继续进行脚本的其余部分。


1
除外test(aka [)抱怨模式是否扩展到多个文件:“期望二进制运算符”或“参数过多”
msw10年

1
@msw-谢谢,我什至都没有想到这个问题。我试图修改我的答案以考虑到它。
dtlussier 2010年

您应该引用变量,即use "$file",因为文件名可能包含一些不良字符,例如空格或星号。
Roman Cheplyaka


2
   shopt -s nullglob
   set -- $(echo *.ext)
    if [ "${#}" -gt 0 ];then
      echo "got file"
    fi

错了 首先,您可能-ge不是而是要使用-gt,因为否则您的代码将无法检测到单个文件。其次,如果没有文件匹配该模式,则任何符合条件的shell都会使该字符串*.ext保持不变,因此您仍然会得到一个“结果”。
Roman Cheplyaka

$#对于单一文件为1,对于没有文件为0。
2015年

2

您可以使用-f检查特定类型的文件是否存在:

#!/bin/bash

if [ -f *.flac ] ; then
   echo true
fi 

这行得通,但您要掩埋书架-之所以起作用,是因为单括号[(而不是更常见的[[)不能防止乱码。
阿德里安·彼得雷斯库

1

仅限bash:

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设置)。


1

这是一个不使用外部命令(即no ls),而是使用shell函数的解决方案。经过bash测试:

shopt -s nullglob
function have_any() {
    [ $# -gt 0 ]
}

if have_any ./*.flac; then
    echo true
fi

该函数have_any用于$#计数其自变量,[ $# -gt 0 ]然后测试是否至少有一个自变量。使用./*.flac而不是仅*.flac在调用中have_any是为了避免由名称为的文件引起的问题--help


1

使用zsh完成:

if [[ -n *.flac(#qN) ]]; then
  echo true
fi

这在zsh手册的“条件表达式”部分的末尾列出。由于[[禁用文件名通配符,因此我们需要(#q)在通配符字符串的末尾使用强制使用文件名生成,然后在不匹配的情况下使用N标志(NULL_GLOB选项)将生成的字符串强制为空。


1

这是一个相当简单的解决方案:

if [ "$(ls -A | grep -i \\.flac\$)" ]; then echo true; fi

如您所见,这只是一行代码,但是效果很好。它应该与bash和dashix等posix兼容外壳一起使用。它也不区分大小写,并且不关心存在什么类型的文件(常规文件,符号链接,目录等),如果您有符号链接或其他内容,这可能会很有用。


我喜欢这个,因为ls -AR进行递归搜索。解压缩后搜索zip归档文件的内容非常有用。
贾斯汀·水芹

0

我尝试了这个:

if [ -f *.html ]; then
    echo "html files exist"
else
    echo "html files dont exist"
fi

我使用这段代码对其他文件没有任何问题,但是对于html文件,我收到了一个错误

[: too many arguments

然后,我尝试了@JeremyWeir的计数解决方案,该解决方案对我有用。

请记住,如果要循环执行此操作,则必须重置计数:

count=$((0))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.